-
Notifications
You must be signed in to change notification settings - Fork 0
/
browser.js
127 lines (106 loc) · 3.9 KB
/
browser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const puppeteer = require('puppeteer')
const OUTLOOK_PAGE = 'https://outlook.live.com/people/0'
const NEW_CONTACT_TEXT = 'New contact'
const EMAIL_INPUT_ID = 'PersonaEmails1-0'
const CREATE_CONTACT_TEXT = 'Create'
const LINKEDIN_TAB_TEXT = 'LinkedIn'
const NO_LINKEDIN_PROFILE_TEXT = 'View search results on LinkedIn'
const POSITIVE_LINKEDIN_TEXTS = [
'See full profile on LinkedIn',
'View profile on LinkedIn'
]
const MORE_TEXT = 'More…'
const CONNECT_TEXT = 'Connect'
const NOTE_INPUT_ID = 'custom-message'
const getButtonXPath = (text) => `//button[contains(., '${text}')]`
const enterText = async (page, inputId, text) => {
const selector = `#${inputId}`
await page.waitForSelector(selector)
await new Promise(r => setTimeout(r, 500))
await page.type(selector, text, { delay: 20 })
}
const clickButton = async (page, text) => {
const buttonXPath = getButtonXPath(text)
await page.waitForXPath(buttonXPath)
const [button] = await page.$x(buttonXPath)
await button.click()
}
const waitForOneOfButtons = async (page, ...buttonsTexts) => {
const xPath = buttonsTexts.map(getButtonXPath).join(' | ')
const button = await page.waitForXPath(xPath)
return button
}
const pressConnectButton = () => {
const CLASS_NAME = 'pv-s-profile-actions--connect'
const [button] = document.getElementsByClassName(CLASS_NAME)
button.click()
}
const pressAddNoteButton = () => {
const ARIA_LABEL = 'Add a note'
const button = document.querySelector(`[aria-label="${ARIA_LABEL}"]`)
button.click()
}
const pressSendButton = () => {
const ARIA_LABEL = 'Send now'
const button = document.querySelector(`[aria-label="${ARIA_LABEL}"]`)
button.click()
}
class Browser {
constructor(browserWSEndpoint) {
this.browserWSEndpoint = browserWSEndpoint
}
async openOutlook() {
this.browser = await puppeteer.connect({
browserWSEndpoint: this.browserWSEndpoint,
defaultViewport: null
})
this.outlookPage = await this.browser.newPage()
await this.outlookPage.goto(OUTLOOK_PAGE)
await this.outlookPage.waitForXPath(`//div[contains(., '${NEW_CONTACT_TEXT}') and @aria-disabled="false"]`)
}
async createContact(email) {
console.log(`Creating contact with email: ${email}`)
await clickButton(this.outlookPage, NEW_CONTACT_TEXT)
await enterText(this.outlookPage, EMAIL_INPUT_ID, email)
await clickButton(this.outlookPage, CREATE_CONTACT_TEXT)
await this.outlookPage.waitForSelector(`#${EMAIL_INPUT_ID}`, { hidden: true })
}
async openLinkedInSection() {
await clickButton(this.outlookPage, LINKEDIN_TAB_TEXT)
}
async getLinkedInButton() {
try {
const button = await waitForOneOfButtons(this.outlookPage, NO_LINKEDIN_PROFILE_TEXT, ...POSITIVE_LINKEDIN_TEXTS)
const text = await this.outlookPage.evaluate(e => e.textContent, button)
const isExists = POSITIVE_LINKEDIN_TEXTS.some(t => text.includes(t))
if (isExists) {
return button
}
} catch (err) {
console.log(`Can't find the LinkedIn button`)
}
}
async connectOnLinkedIn(button, note) {
await button.click()
const linkedInPage = await new Promise(x => this.browser.once('targetcreated', target => x(target.page())))
try {
await waitForOneOfButtons(linkedInPage, CONNECT_TEXT, MORE_TEXT)
await linkedInPage.evaluate(pressConnectButton)
await linkedInPage.evaluate(pressAddNoteButton)
await enterText(linkedInPage, NOTE_INPUT_ID, note)
await linkedInPage.evaluate(pressSendButton)
await linkedInPage.waitForSelector(`#${NOTE_INPUT_ID}`, { hidden: true })
} catch (err) {
console.log('Fail to connect: ', err)
}
const url = linkedInPage.url()
const splittedUrl = url.split('/')
const [linkedInProfile] = splittedUrl[splittedUrl.indexOf('in') + 1].split('?')
await linkedInPage.close()
return decodeURI(linkedInProfile)
}
async close() {
await this.browser.close()
}
}
module.exports = Browser