Files
puppeteerjs/src/workers/CommandorPage.js
T
2023-12-05 14:08:02 +01:00

1245 lines
50 KiB
JavaScript

const {SolveCaptcha, TWO_CAPTCHA_CONNECTION_FAILED} = require("./SolveCaptcha");
const ReserveResultPojo = require("../models/ReserveResultPojo");
const appointmentLogger = require("../utiles/LoggerUtils")
const OCRResult = require("../models/OCRResult");
const PublishType = require("../models/PublishType");
const puppeteer = require('puppeteer');
const GeoCaptchaSolver = require("./GeoCaptchaSolver");
const SlidingCaptchaSolver = require("./SlidingCaptchaSolver");
const OCRChecker = require("./OCRChecker");
const {exec} = require("child_process");
const {openUrlWithAdb} = require("../utiles/CmdUtils");
// const RDV_URL = "http://192.168.0.44:8000/test_appointment.html"
const RDV_URL = "https://rendezvousparis.hermes.com/client/register";
const BLANK_URL = "about:blank"
const ERROR_CAPTCHA_UNSOLVABLE = "ERROR_CAPTCHA_UNSOLVABLE";
const COUNTRY_ID = "#phone_country"
const PHONE_NUMBER = "#phone_number"
const EMAIL_ID = "#email"
const PREFER_STORE = "#prefer"
const LAST_NAME = "#surname"
const FIRST_NAME = "#name"
const CGU_ID = "#cgu"
const PROCESSING_ID = "#processing"
const PASSPORT_ID = "#passport_id"
const CAPTCHA_CONTAINER = "#captcha-container";
const TIME_OUT = 60 * 1000 * 4//4 mins
const EMPTY_RESPONSE_ERROR = "ERR_EMPTY_RESPONSE"
const MESSAGE_URL_VALIDATION_FR = "Nous avons envoyé un lien par e-mail."
const MESSAGE_URL_VALIDATION_EN = "Please click on the link we sent by email"
const REGEX_RDV_URL = "https:\/\/rendezvousparis\.hermes\.com\/client\/register\/[A-Z0-9]+"
const DEFAULT_STORE = 'faubourg';
const timeout = (prom, time) =>
Promise.race([prom, new Promise((_r, rej) => setTimeout(rej, time))]);
function delay(delayInMs) {
return new Promise(resolve => {
setTimeout(() => {
resolve(2);
}, delayInMs);
});
}
function getRandom() {
return Math.floor(Math.random() * 3);
}
function getRandomWaitTime() {
return getRandom() * 1000
}
function log(message) {
appointmentLogger.log({level: "info", message: message})
}
async function clearApp(device, packageName) {
let cmd = `adb -s ${device.serial()} shell pm clear ${packageName}`
logWithDevice("cmd is " + cmd, device)
await exec(cmd);
}
async function exceutShellCmd(device, cmdToExecut) {
let cmd = `adb -s ${device.serial()} shell ${cmdToExecut}`
logWithDevice("cmd is " + cmd, device)
await exec(cmd);
}
function logWithDevice(message, device) {
appointmentLogger.log({level: "info", message: device.model() + ":" + device.serial() + ":" + message})
}
class CommandorPage {
constructor(contact, device, mongoManager, selectedStore = DEFAULT_STORE, audioAnalyse = false, alertBeep = false, port = 9000) {
this.contact = contact;
this.device = device;
this.mongoManager = mongoManager;
this.selectedStore = selectedStore;
this.choosedStore = selectedStore;
this.port = port;
this.ocrChecker = new OCRChecker(this.device, this.contact);
this.browserPackageName = "com.brave.browser";
// this.browserPackageName = "com.android.chrome";
this.isFillingFields = false;
this.isTerminated = false;
this.cguChecked = false;
this.isNameInput = false;
this.isEmailFilled = false;
this.isCountryChoosen = false;
this.isPhoneInput = false;
this.firstStart = true;
}
async connect_to_browser(ocrResult) {
console.log("connect_to_browser() called");
if (this.browser === undefined) {
this.isTerminated = true
return
}
console.log("browser.isConnected: " + this.browser.isConnected());
if (!this.browser.isConnected()) {
this.browser = await puppeteer.connect({
browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
headless: false, defaultViewport: null
})
}
let pages = await this.browser.pages();
// 0 is the last page
pages.forEach((currentPage) => {
let url = currentPage.url()
if (url.includes(RDV_URL)) {
this.page = currentPage
}
})
logWithDevice("pageUrl is " + this.page.url(), this.device)
// this.page = pages[pages.length - 1];
switch (ocrResult) {
case OCRResult.SUCCESS:
// get url and push to server
await this.push_message_to_queue(PublishType.SUCCESS)
break;
case OCRResult.RECAPTCHA_ERROR:
// get url and push to server
await this.fillFields()
break;
case OCRResult.SLIDING_CAPTCHA_REFRESH:
pages.forEach((currentPage) => {
currentPage.close()
})
break;
case OCRResult.TO_REFRESH:
logWithDevice("will reload page", this.device)
let cmd = "input swipe 382 682 382 1682"
logWithDevice("will send cmd:" + cmd, this.device)
this.device.shell(cmd);
await delay(3000);
await this.clickOnConfirmBtn();
await this.checkResultWithOcr();
break;
}
}
async checkIfSuccessful() {
let content = await this.page.content();
if (content.includes(MESSAGE_URL_VALIDATION_FR) || content.includes(MESSAGE_URL_VALIDATION_EN)) {
log("successful");
await this.push_message_to_queue(PublishType.SUCCESS);
return true;
} else {
return false
}
}
async loadPage() {
logWithDevice(this.device.serial() + ":loadPage() called, with port:" + this.port, this.device);
try {
// let cmd = 'adb -s ' + device.serial() + " forward tcp:" + attributedPort + " localabstract:chrome_devtools_remote";
await exceutShellCmd(this.device, " forward tcp:" + this.port + " localabstract:chrome_devtools_remote")
await delay(1 * 1000);
// await this.startPage(this.device, this.browserPackageName + "/com.google.android.apps.chrome.Main")
await delay(4 * 1000);
} catch (e) {
console.log(e)
this.isTerminated = true;
}
// await this.acceptCookies();
await this.enableDisableAirPlanMode();
// await delay(10 * 1000);
await openUrlWithAdb(RDV_URL, this.device)
await delay(15000)
await this.checkResultWithOcr()
// await this.clickOnlineAppointment();
// } else {
// this.isTerminated = true;
// }
let cancel
const intervalTask = setInterval(async () => {
if (this.isTerminated) {
log(this.device.model() + ":request terminated, send cancel()");
try {
if (this.page !== undefined) {
await this.page.close()
}
} catch (e) {
console.log(e)
}
this.disconnectBrowser();
clearInterval(intervalTask)
cancel()
} else {
}
}, 10 * 1000)//interval of 10 seconds
await new Promise(function (fulfill, reject) {
cancel = function () {
fulfill(Promise.resolve())
}
setTimeout(fulfill, TIME_OUT, 5)
}).then(log)
}
async clickOnlineAppointment() {
try {
logWithDevice("will click on rdv link", this.device);
await this.connectBrowserIfNecessary();
const [button] = await this.page.$x("//a[contains(., 'rendezvousparis')]");
console.log("button is " + button)
if (button) {
console.log("will click on the button")
try {
await button.click();
if (this.firstStart) {
this.disconnectBrowser()
}
await delay(2000)
await this.checkResultWithOcr();
} catch (e) {
console.log(e)
}
}
} catch (e) {
console.log(e)
await this.checkResultWithOcr();
}
}
async acceptCookies() {
logWithDevice("will accept Cookies", this.device);
if (this.browser.isConnected() && !this.page.isClosed()) {
try {
await this.page.evaluate(() => {
let buttons = document.getElementsByTagName('button');
for (let i = 0; i < buttons.length; i++) {
let button = buttons[i];
let txt = button.textContent || button.innerText;
if (txt.includes("Tout accepter")) {
button.click()
}
console.log(txt);
}
})
} catch (e) {
console.log(e)
}
}
}
async chooseCountry(page) {
logWithDevice("chooseCountry", this.device)
if (this.browser.isConnected() && !this.isTerminated) {
try {
if (!this.isCountryChoosen) {
// await page.focus(COUNTRY_ID);
// await delay(getRandomWaitTime())
// await page.click(COUNTRY_ID);
// await delay(getRandomWaitTime())
await page.select(COUNTRY_ID, 'FR');
await delay(getRandomWaitTime())
this.isCountryChoosen = true;
}
} catch (e) {
log(e);
this.isTerminated = true;
}
}
}
async fillEmail(page) {
logWithDevice("fillEmail", this.device)
try {
if (this.browser.isConnected() && !this.isTerminated) {
if (!this.isEmailFilled) {
await page.focus(EMAIL_ID);
await delay(getRandomWaitTime())
console.log("will clear email field");
await page.evaluate((email) => {
let field = document.getElementById("email");
if (field) {
field.value = email
}
}, this.contact.mail)
// await page.evaluate(() => {
// let field = document.getElementById("email");
// if (field) {
// field.value = ""
// }
// })
// await delay(1000);
// await page.keyboard.type(this.contact.mail);
this.isEmailFilled = true;
}
}
} catch (e) {
log(e)
}
}
async inputPhoneNumber(page) {
logWithDevice("inputPhoneNumber", this.device)
try {
if (this.browser.isConnected() && !this.isTerminated) {
if (!this.isPhoneInput) {
await page.focus(PHONE_NUMBER);
console.log("will clear phone_number field");
await page.evaluate((phone) => {
let field = document.getElementById("phone_number");
if (field) {
field.value = phone
}
}, "" + this.contact.phoneNumber)
// }, "0" + this.contact.phoneNumber)
// 如果需要显示键盘的话,使用下面方法
// await page.evaluate(() => {
// let field = document.getElementById("phone_number");
// if (field) {
// field.value = ""
// }
// })
// await delay(1000);
// await page.keyboard.type("0" + this.contact.phoneNumber);
this.isPhoneInput = true;
}
}
} catch (e) {
log(e);
this.isTerminated = true;
}
}
async inputName(page) {
logWithDevice("inputName", this.device)
await delay(getRandomWaitTime());
try {
logWithDevice("input name called with this.browser.isConnected=" + this.browser.isConnected(), this.device)
logWithDevice("input name called with this.isNameInput=" + this.isNameInput, this.device)
if (this.browser.isConnected() && !this.isTerminated && !this.page.isClosed()) {
if (!this.isNameInput) {
await page.focus(LAST_NAME);
await delay(getRandomWaitTime());
console.log("will clear surname field");
await page.evaluate(() => {
let field = document.getElementById("surname");
if (field) {
field.value = ""
}
})
await delay(1000);
// await page.keyboard.type(this.contact.lastName);
await page.evaluate((lastName) => {
let field = document.getElementById("surname");
if (field) {
field.value = lastName
}
}, this.contact.lastName)
await page.focus(FIRST_NAME);
await delay(getRandomWaitTime());
// console.log("will clear name field");
await page.evaluate((firstName) => {
let field = document.getElementById("name");
if (field) {
field.value = firstName;
// field.value = ""
}
}, this.contact.firstName)
// await page.keyboard.type(this.contact.firstName);
this.isNameInput = true;
}
}
} catch (e) {
logWithDevice("exception while inputting name", this.device)
console.log(e);
this.isTerminated = true
}
}
async getRawAppointmentInfo(page) {
let passportId = await page.evaluate(() => {
let field = document.getElementById("passport_id");
return field.value
})
let lastName = await page.evaluate(() => {
let field = document.getElementById("surname");
return field.value
})
let firstName = await page.evaluate(() => {
let field = document.getElementById("name");
return field.value
})
let phone = await page.evaluate(() => {
let field = document.getElementById("phone_number");
return field.value
})
let email = await page.evaluate(() => {
let field = document.getElementById("email");
return field.value
})
return new ReserveResultPojo(email, phone, passportId, email, lastName, firstName, "random", "", PublishType.PENDING)
}
async inputPassportId(page) {
logWithDevice("inputPassportId", this.device)
try {
if (this.browser.isConnected() && !this.isTerminated) {
if (!this.isPasspordInput) {
await page.focus(PASSPORT_ID);
await delay(getRandomWaitTime());
console.log("will clear passport_id field");
await page.evaluate((passport) => {
let field = document.getElementById("passport_id");
if (field) {
field.value = passport
}
}, this.contact.passportNumber.toString())
// await page.evaluate(() => {
// let field = document.getElementById("passport_id");
// if (field) {
// field.value = ""
// }
// })
// await delay(1000);
// await page.keyboard.type(this.contact.passportNumber.toString());
this.isPasspordInput = true;
}
}
} catch (e) {
log(e);
this.isTerminated = true;
}
}
async checkCGU(page) {
logWithDevice("checkCGU", this.device)
try {
if (this.browser.isConnected() && !this.isTerminated && !this.page.isClosed()) {
if (!this.cguChecked) {
await page.focus(CGU_ID);
await page.evaluate(() => {
if (!document.querySelector("#cgu").checked) {
document.querySelector("#cgu").checked = true
}
});
// await page.click(CGU_ID);
await delay(getRandomWaitTime());
await page.focus(PROCESSING_ID);
// await page.click(PROCESSING_ID)
await page.evaluate(() => {
if (!document.querySelector("#processing").checked) {
document.querySelector("#processing").checked = true
}
});
this.cguChecked = true;
}
}
} catch (e) {
log(e);
this.isTerminated = true;
}
}
async chooseStore(page) {
logWithDevice("chooseStore", this.device)
await delay(getRandomWaitTime())
try {
if (!this.page.isClosed() && !this.isTerminated) {
if (this.contact.store === undefined || this.contact.store.length === 0) {
this.contact.store = this.selectedStore;
} else {
this.selectedStore = this.contact.store;
}
if (this.contact.store !== "random") {
// page.focus(PREFER_STORE);
await delay(500)
// page.click(PREFER_STORE);
let stores = this.contact.store.split(":")
this.choosedStore = stores[Math.floor(Math.random() * stores.length)]
await page.select(PREFER_STORE, this.choosedStore);
}
}
} catch (e) {
log(e);
// this.isTerminated = true;
}
}
async fillFields(page) {
logWithDevice("fillFields called for contact: " + this.contact.mail, this.device)
logWithDevice("this.isFillingFields: " + this.isFillingFields, this.device);
logWithDevice("this.isTerminated: " + this.isTerminated, this.device);
if (!this.isFillingFields && !this.isTerminated && !this.page.isClosed()) {
this.isFillingFields = true;
await this.chooseStore(page);
await this.inputName(page);
// await this.chooseCountry(page);
await this.inputPhoneNumber(page)
await this.fillEmail(page)
await this.inputPassportId(page)
await this.checkCGU(page)
let pageContent = await page.content()
let hasCaptcha = pageContent.includes("g-recaptcha-response")
if (hasCaptcha) {
await this.resolveCaptcha(page);
await delay(getRandomWaitTime());
this.isFillingFields = false;
} else {
await delay(getRandomWaitTime())
try {
await this.clickValid();
} catch (e) {
this.isTerminated = true;
console.log(e)
}
this.isFillingFields = false
}
}
}
async clickValid() {
logWithDevice("clickValid() called.", this.device);
await delay(getRandomWaitTime())
this.isFillingFields = false
try {
if (!this.page.isClosed()) {
if (!this.page.isClosed()) {
try {
// remove debug flag
// const validElement = await page.$('.btn');
logWithDevice("will click on valid button", this.device);
logWithDevice("isTerminated is " + this.isTerminated, this.device);
if (!this.isTerminated) {
if (!this.page.isClosed()) {
let raw = await this.getRawAppointmentInfo(this.page)
if (raw.email !== undefined) {
this.contact.mail = raw.email
}
if (raw.passportNumber !== undefined) {
this.contact.passportNumber = raw.passportNumber
}
if (raw.lastName !== undefined) {
this.contact.lastName = raw.lastName
}
if (raw.phoneNumber !== undefined) {
this.contact.phoneNumber = raw.phoneNumber
}
if (raw.firstName !== undefined) {
this.contact.firstName = raw.firstName
}
await this.page.evaluate(() => {
document.getElementsByClassName("btn")[0].click();
})
if (this.firstStart) {
this.disconnectBrowser();
await delay(3000);
await this.checkResultWithOcr();
}
}
}
} catch (e) {
log(e);
await this.checkResultWithOcr()
}
}
}
} catch (e) {
logWithDevice("exception received", this.device)
log(e)
}
}
async resolveCaptcha(page) {
logWithDevice("resolveCaptcha", this.device)
if (RDV_URL.includes("192")) {
// await this.push_message_to_queue(PublishType.SUCCESS)
await delay(100000)
return
}
try {
//check whether there is captcha
let pageContent = await page.content()
let hasCaptcha = pageContent.includes("g-recaptcha-response")
logWithDevice("hasCaptcha = " + hasCaptcha, this.device)
if (hasCaptcha) {
// await this.clickCheckbox()
await delay(1000)
this.captchaSolver = new SolveCaptcha(page);
await this.captchaSolver.start((solution) => {
logWithDevice("solution is: " + solution, this.device);
if (solution !== ERROR_CAPTCHA_UNSOLVABLE && solution !== TWO_CAPTCHA_CONNECTION_FAILED) {
try {
if (!page.isClosed() && !this.isTerminated) {
if (this.browser.isConnected()) {
page.evaluate((solution) => {
let element = document.getElementById("g-recaptcha-response");
if (element != null)
document.getElementById("g-recaptcha-response").innerHTML = solution;
}, solution)
this.clickValid();
}
}
} catch (e) {
log(e)
this.isTerminated = true;
}
} else {
this.isTerminated = true;
}
})
} else {
await this.clickValid();
}
} catch (e) {
console.log(e)
this.isTerminated = true;
}
}
async onPageLoad(currentPage) {
logWithDevice("onPageLoad called with url " + this.page.url(), this.device)
try {
let content = await this.page.content();
let captcha_url = "geo.captcha-delivery.com/captcha";
// if (content.toString().includes(captcha_url)) {
// await this.checkResultWithOcr()
// logWithDevice("发现datadome", this.device);
// } else
if (content.includes("502 Bad Gateway")) {
logWithDevice("502 Bad Gateway found", this.device)
await this.page.reload()
} else if (this.page.url().includes("sorry")) {
await this.resetBrowser()
} else if (content.includes("PROXY_CONNECTION_FAILED")) {
logWithDevice("PROXY_CONNECTION_FAILED, will reload page", this.device);
await delay(2000)
await this.page.reload()
} else if (content.includes("ERR_NETWORK_CHANGED")) {
logWithDevice("ERR_NETWORK_CHANGED, will reload page", this.device);
await delay(2000)
await this.page.reload()
} else if (content.includes("ERR_TIMED_OUT")) {
logWithDevice("ERR_TIMED_OUT, will reload page", this.device);
await delay(2000)
await this.page.reload()
} else if (content.includes("408 Request Time-out")) {
logWithDevice("Request Time-out, will reload page", this.device);
await delay(2000)
await this.page.reload()
} else {
if (this.page.url() === RDV_URL) {
await this.fillFields(this.page);
} else {
if (content.includes(MESSAGE_URL_VALIDATION_FR) || content.includes(MESSAGE_URL_VALIDATION_EN)) {
log("successful");
await this.push_message_to_queue(PublishType.SUCCESS);
} else if (content.includes(EMPTY_RESPONSE_ERROR)) {
log("EMPTY_RESPONSE_ERROR error received, will quit")
this.isTerminated = true
} else {
// try to get errors
await this.getErrors()
}
}
}
} catch (e) {
log(e)
}
}
async slidingCaptcha(onResult) {
logWithDevice("slidingCaptcha", this.device);
if (this.device.model() === "MI 5s" || this.device.model() === "ASUS_X00QD" || this.device.model() === "ASUS_Z012D" || this.device.model() === "HUAWEI NXT-TL00") {
let cmd = `adb -s ${this.device.serial()} shell input touchscreen swipe 900 495 900 195`
await exec(cmd);
await delay(5000);
}
let slidingCaptchaSolver = new SlidingCaptchaSolver(this.device);
await slidingCaptchaSolver.solve(this.page, async (isSuccessful) => {
console.log("check isAlwaysBlocked")
this.isFillingFields = false
onResult(isSuccessful)
})
}
async onResponse(response) {
let rex = new RegExp(REGEX_RDV_URL)
// log("onResponse with url:" + response.url())
// log("onResponse with url:" + response.body())
if (rex.test(response.url())) {
logWithDevice("rdv url found:" + response.url(), this.device)
// save cookies
await this.push_message_to_db(PublishType.SUCCESS, response.url())
}
}
async push_message_to_queue(publishType) {
let url = this.page.url();
logWithDevice("successful url is " + url, this.device)
await this.push_message_to_db(publishType, url)
// this.firstStart = false;
}
async push_message_to_db(publishType, url) {
let splitedUrl = url.split("/");
let id = splitedUrl[splitedUrl.length - 1];
if (id === "register") {
id = this.contact.mail;
}
if (url === "https://rendezvousparis.hermes.com/client/welcome") {
return
}
// save to mongoDb
let reserve = ReserveResultPojo.create_from_contact(this.contact, id, url, this.choosedStore, publishType);
reserve.source_from = this.device.model();
await this.mongoManager.saveReserveToDb(reserve.to_mongo_dict())
await this.page.close();
// await this.deleteFromBlackList()
// await this.resetBrowser()
this.isTerminated = true
}
async getErrors() {
logWithDevice("getErrors", this.device);
await this.checkResultWithOcr();
if (this.page.url() === BLANK_URL) {
this.isTerminated = true;
}
}
async clickCheckbox() {
logWithDevice("clickCheckbox", this.device);
try {
// let errorItem = await this.page.click("#recaptcha-anchor > div.recaptcha-checkbox-border")
await this.page.waitForSelector("iframe")
let elementHandle = await this.page.$('[title="reCAPTCHA"]')
const iframe = await elementHandle.contentFrame()
await iframe.click("#recaptcha-anchor > div.recaptcha-checkbox-border")
} catch (e) {
log(e);
}
}
async resetBrowser() {
logWithDevice("resetBrowser", this.device);
this.isFillingFields = false;
this.cguChecked = false;
this.isNameInput = false;
this.isEmailFilled = false;
this.isCountryChoosen = false;
this.isPhoneInput = false;
this.isPasspordInput = false;
await clearApp(this.device, this.browserPackageName)
// await this.device.shell("pm clear " + this.browserPackageName)
await delay(1000)
this.isTerminated = true;
// await this.checkResultWithOcr();
}
disconnectBrowser() {
try {
logWithDevice("will disconnect browser", this.device);
if (this.browser !== undefined) {
this.browser.disconnect();
}
} catch (e) {
console.log(e)
}
}
async connectBrowserIfNecessary() {
if (!this.browser.isConnected()) {
try {
this.browser = await puppeteer.connect({
browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
headless: false, defaultViewport: null
})
} catch (e) {
console.log(e)
this.isTerminated = true;
}
}
}
async checkResultWithOcr() {
logWithDevice("checkResultWithOcr() called.", this.device)
if (this.device.model() === "M2006C3LG")
await delay(6000);
else {
await delay(4000);
}
let checkResult = await this.ocrChecker.get_result();
console.log(checkResult);
while (checkResult === OCRResult.RECHECK || checkResult === OCRResult.NO_INTERNET) {
logWithDevice("will recheck OCR", this.device)
await delay(4000)
logWithDevice("will recheck OCR", this.device)
checkResult = await this.ocrChecker.get_result();
}
while (checkResult === OCRResult.SLIDING_CAPTCHA) {
await this.slidingCaptcha(async (isSuccessful) => {
logWithDevice("SLIDING_CAPTCHA result is " + isSuccessful, this.device)
if (isSuccessful) {
await delay(5 * 1000)
checkResult = await this.ocrChecker.get_result();
console.log(checkResult);
} else {
checkResult = OCRResult.TERMINAED
this.isTerminated = true
}
})
await delay(10 * 1000)
}
switch (checkResult) {
case OCRResult.SLIDING_CAPTCHA_LOADING:
this.isTerminated = true;
break;
case OCRResult.SSL_CERT_ERROR:
await this.resetBrowser()
break;
case OCRResult.TERMINAED:
this.isTerminated = true;
break;
case OCRResult.SLIDING_CAPTCHA_REFRESH:
await this.connect_to_browser(checkResult)
break;
case OCRResult.FILL_FIELD:
logWithDevice("FILL_FIELD", this.device)
if (this.browser === undefined || !this.browser.isConnected()) {
logWithDevice("trying to connect to browser", this.device)
try {
this.browser = await puppeteer.connect({
browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser",
headless: false, defaultViewport: null
})
try {
logWithDevice("get pages", this.device)
// let pages = await this.browser.pages();
let pages = await timeout(this.browser.pages(), 5 * 1000);
pages.forEach((currentPage) => {
if (currentPage.url() === RDV_URL) {
this.page = currentPage;
} else {
try {
currentPage.close()
} catch (e) {
console.log(e)
}
}
})
logWithDevice("this.page.bringToFront();", this.device)
await this.page.bringToFront();
await this.fillFields(this.page)
await delay(2 * 1000);
} catch (e) {
console.log(e)
await this.resetBrowser()
// this.isTerminated = true;
}
// try {
// for (const currentPage of pages) {
// if (currentPage.url() === RDV_URL) {
// logWithDevice("get content", this.device)
// let pageContent = await currentPage.content()
// logWithDevice("content:" + pageContent, this.device)
// if (!pageContent.includes("geo.captcha-delivery.com")) {
// this.page = currentPage;
// break
// } else {
// try {
// await currentPage.close()
// } catch (e) {
// console.log(e)
// }
// }
// } else {
// try {
// await currentPage.close()
// } catch (e) {
// console.log(e)
// }
// }
// }
// } catch (e) {
// this.isTerminated = true;
// console.log(e)
// }
} catch (e) {
console.log(e)
this.isTerminated = true
}
} else {
logWithDevice("this.browser.isConnected() is " + this.browser.isConnected(), this.device)
try {
if (this.browser.isConnected()) {
logWithDevice("will use old page", this.device)
logWithDevice("this.page.bringToFront();", this.device)
await this.page.bringToFront();
// this.page = pages;
// this.page.await
await this.fillFields(this.page)
await delay(2 * 1000);
}
} catch
(e) {
console.log(e)
this.isTerminated = true
}
}
break;
case
OCRResult.SUCCESS:
// reconnect to page and get url
if (!this.isTerminated) {
await this.connect_to_browser(OCRResult.SUCCESS)
// if (!this.isTerminated) {
// logWithDevice("will save success appointment", this.device)
// await this.push_message_to_queue(PublishType.SUCCESS);
// await this.closePage()
// }
}
break;
case
OCRResult.RECAPTCHA_ERROR:
// if (!this.isFillingFields)
this.isTerminated = true;
// else {
// await this.checkResultWithOcr();
// }
// await this.connect_to_browser(OCRResult.RECAPTCHA_ERROR)
break;
case
OCRResult.BRAVE_SKIP:
await this.handleBraveSkipBtn();
await this.checkResultWithOcr();
break;
case OCRResult.BRAVE_PRIVACY:
let model = this.device.model()
if (model === "MI 5s" || this.device.model() === "SM-G965U1" || this.device.model() === "ASUS_Z012D") {
await this.tapForDevice(this.device, 530, 970)
} else if (model === "HUAWEI NXT-TL00") {
await this.tapForDevice(this.device, 530, 950)
} else if (this.device.model() === "ONEPLUS A6000") {
await this.tapForDevice(this.device, 530, 1064)
} else if (this.device.model() === "moto g51 5G") {
await this.tapForDevice(this.device, 500, 1080)
} else if (this.device.model() === "M2006C3LG" || this.device.model() === "220233L2G") {
await this.tapForDevice(this.device, 350, 777)
} else if (this.device.model() === "KB2003" || this.device.model() === "DE2117") {
await this.tapForDevice(this.device, 500, 1200)
await this.tapForDevice(this.device, 500, 1120)
} else
try {
await this.tapForDevice(this.device, 500, 1120)
// await this.device.shell("input tap " + 500 + " " + 1120)
} catch (e) {
console.log(e)
}
await delay(2000);
await this.checkResultWithOcr();
break;
case OCRResult.BRAVE_PRIVACY_PUB:
if (this.device.model() === "MI 5s" || this.device.model() === "ASUS_Z012D") {
await this.tapForDevice(this.device, 60, 1400)
} else if (this.device.model() === "HUAWEI NXT-TL00") {
await this.tapForDevice(this.device, 530, 950)
} else
await this.tapForDevice(this.device, 455, 1920)
await delay(2000);
await this.checkResultWithOcr();
break;
case OCRResult.BRAVE_NOTIFICATION:
logWithDevice("BRAVE_NOTIFICATION", this.device)
if (this.device.model() === "21091116C") {
await this.tapForDevice(this.device, 540, 1611)
} else if (this.device.model() === "22041219PG") {
await this.tapForDevice(this.device, 530, 1600)
} else
await this.tapForDevice(this.device, 500, 1680)
// await this.device.shell("input tap " + 500 + " " + 1680)
await delay(2000);
await this.checkResultWithOcr();
break;
case OCRResult.CHOOSE_POSITION:
logWithDevice("CHOOSE_POSITION", this.device)
await this.tapForDevice(this.device, 300, 1300)
await delay(2000);
await this.tapForDevice(this.device, 300, 1700)
await this.checkResultWithOcr();
break;
case OCRResult.BRAVE_VPN_SKIP:
logWithDevice("BRAVE_VPN_SKIP", this.device)
if (this.device.model() === "M2006C3LG") {
await this.tapForDevice(this.device, 580, 445)
}
break;
case OCRResult.TO_SKIP
:
logWithDevice("TO_SKIP", this.device)
if (this.device.model() === "21091116C")
await this.device.shell("input tap " + 530 + " " + 1742)
else
await this.device.shell("input tap " + 488 + " " + 1848)
await delay(2000);
break;
case
OCRResult.TO_REFRESH
:
await this.connect_to_browser(OCRResult.TO_REFRESH)
break;
case
OCRResult.BLOCKED
:
await this.resetBrowser();
break;
case
OCRResult.ONLINE_APPOINTMENT
:
await this.clickOnlineAppointment();
break;
case
OCRResult.CONFIRM_RESEND_FORM
:
// logWithDevice("CONFIRM_RESEND_FORM", this.device)
// await this.checkResultWithOcr();
break;
case
OCRResult.PAGE_OPTIMIZATION
:
logWithDevice("PAGE_OPTIMIZATION", this.device)
await this.skipOptimizationPage();
await this.checkResultWithOcr();
break;
case
OCRResult.GOOGLE_DISCONNECT
:
logWithDevice("GOOGLE_DISCONNECT", this.device)
await this.tapGoogleDisconnectBtn()
await this.checkResultWithOcr();
break
case
OCRResult.NEED_TO_CLICK_LATE_BTN
:
await this.tapLaterBtn()
this.firstStart = true;
await this.loadPage()
break;
case
OCRResult.CLOSED
:
await this.closePage();
// this.isTerminated = true;
break;
default:
await delay(5000);
checkResult = this.ocrChecker.get_result();
}
if (checkResult
===
undefined
) {
await
delay(
5000
)
;
checkResult = this.ocrChecker.get_result();
}
}
async handleBraveSkipBtn() {
let model = this.device.model()
if (model === "CPH2219") {
await this.device.shell("input tap " + 558 + " " + 1160)
} else if (model === "MI 5s" || model === "ASUS_Z012D") {
await this.tapForDevice(this.device, 530, 1000)
} else if (model === "SM-G965U1") {
await this.tapForDevice(this.device, 530, 1000)
} else if (model === "HUAWEI NXT-TL00") {
await this.tapForDevice(this.device, 530, 950)
} else if (model === "M2006C3LG" || model === "220233L2G") {
await this.tapForDevice(this.device, 360, 777)
} else if (model === "ONEPLUS A6000") {
await this.tapForDevice(this.device, 530, 1045)
} else {
logWithDevice("handleBraveSkipBtn", this.device)
await this.tapForDevice(this.device, 470, 1160)
}
await delay(2000);
await this.tapForDevice(this.device, 455, 1920)
await delay(1000);
}
async tapForDevice(device, x, y) {
let cmd = `adb -s ${device.serial()} shell input tap ${x} ${y}`
logWithDevice("cmd is " + cmd, this.device)
await exec(cmd);
}
async clickOnConfirmBtn() {
if (this.device.model() === "CPH2219") {
this.device.shell("input tap " + 900 + " " + 1532)
} else if (this.device.model() === "MI 5s") {
this.device.shell("input tap " + 925 + " " + 1325)
} else if (this.device.model() === "22041219PG") {
this.device.shell("input tap " + 925 + " " + 1430)
} else if (this.device.model() === "moto g51 5G") {
await this.tapForDevice(this.device, 950, 1434)
} else
this.device.shell("input tap " + 933 + " " + 1538)
await delay(2000);
}
async closePage() {
await this.resetBrowser();
}
async skipOptimizationPage() {
logWithDevice("skipOptimizationPage", this.device)
let model = this.device.model();
if (model === "ASUS_X00QD") {
this.device.shell("input tap " + 800 + " " + 2100)
await delay(2000);
this.device.shell("input tap " + 800 + " " + 2100)
await delay(1000);
} else if (model === "ONEPLUS A6000") {
this.device.shell("input tap " + 818 + " " + 2140)
await delay(2000);
this.device.shell("input tap " + 818 + " " + 2140)
await delay(1000);
} else if (model === "CPH2219") {
this.device.shell("input tap " + 772 + " " + 2146)
await delay(2000);
this.device.shell("input tap " + 772 + " " + 2146)
} else if (model === "MI 5s") {
this.device.shell("input tap " + 786 + " " + 1780)
await delay(2000);
this.device.shell("input tap " + 790 + " " + 1807)
await delay(1000);
} else {
this.device.shell("input tap " + 800 + " " + 2215)
await delay(2000);
this.device.shell("input tap " + 800 + " " + 2215)
await delay(1000);
}
}
async tapLaterBtn() {
logWithDevice("tapLaterBtn", this.device)
let model = this.device.model();
log("model is " + model);
if (model === "CPH2219") {
this.device.shell("input tap " + 385 + " " + 1930)
} else if (model === "ASUS_X00QD") {
this.device.shell("input tap " + 490 + " " + 1910)
} else if (model === "Mi Note 10") {
this.device.shell("input tap " + 550 + " " + 1920)
} else if (model === "ONEPLUS A6000") {
this.device.shell("input tap " + 535 + " " + 1945)
} else if (model === "22041219PG") {
this.device.shell("input tap " + 540 + " " + 1985)
} else if (model === "21091116C") {
this.device.shell("input tap " + 510 + " " + 1975)
} else if (model === "MI 5s") {
this.device.shell("input tap " + 510 + " " + 1615)
} else
this.device.shell("input tap " + 385 + " " + 2050)
await delay(1000);
}
async enableDisableAirPlanMode() {
logWithDevice("will enable/disable airplane mode", this.device)
// try {
// // await this.device.shell("cmd connectivity airplane-mode enable")
// await exceutShellCmd(this.device, "cmd connectivity airplane-mode enable")
// await delay(1000)
// await exceutShellCmd(this.device, "cmd connectivity airplane-mode disable")
// // await this.device.shell("cmd connectivity airplane-mode disable")
// await delay(2000)
// } catch (e) {
// try {
// await this.device.shell("cmd connectivity airplane-mode disable")
// } catch (e) {
// console.log(e)
// }
// console.log(e)
// }
}
async tapGoogleDisconnectBtn() {
if (this.device.model() === "MI 5s") {
if (this.browserPackageName.includes("brave")) {
await this.tapForDevice(this.device, 535, 1629)
} else
await this.device.shell("input tap " + 550 + " " + 1740)
} else {
if (this.browserPackageName.includes("brave") && this.device.model() === "CPH2219") {
await this.device.shell("input tap " + 411 + " " + 1977)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "RMX3151") {
await this.device.shell("input tap " + 411 + " " + 1977)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "ONEPLUS A6000") {
await this.device.shell("input tap " + 411 + " " + 1970)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "ASUS_X00QD") {
await this.device.shell("input tap " + 411 + " " + 1970)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "22041219PG") {
await this.tapForDevice(this.device, 411, 2020)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "21091116C") {
await this.tapForDevice(this.device, 411, 2020)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "M2006C3LG") {//redmi 9a
await this.tapForDevice(this.device, 411, 1300)
} else if (this.browserPackageName.includes("brave") && this.device.model() === "220233L2G") {//redmi 9a
await this.tapForDevice(this.device, 411, 1300)
} else {
await this.tapForDevice(this.device, 411, 2100)
}
// await this.device.shell("input tap " + 411 + " " + 2100)
}
await delay(2000);
}
async startPage(device, activity) {
let cmd = `adb -s ${device.serial()} shell am start -n ${activity}`
logWithDevice("cmd is " + cmd, this.device)
await exec(cmd);
}
}
module
.exports = CommandorPage