const {SolveCaptcha, TWO_CAPTCHA_CONNECTION_FAILED} = require("./SolveCaptcha"); const ReserveResultPojo = require("../models/ReserveResultPojo"); const BlackListContactPojo = require("../models/BlackListContactPojo"); 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 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 searchTexts = ['hermes+rdv+online+paris', 'hermes+rdv+enligne+paris', 'hermes+rdv+en+ligne+paris', 'hermes+rendezvous+en+ligne+paris', 'hermes+appointment+online+paris', 'hermes+appointment+online+paris', 'appointment+hermes+paris+on+line', 'hermes+rendez+vous+online+paris', 'hermes+rendez+vous+paris+en+ligne', 'hermes+rendez+vous+paris+enligne', 'hermes+rendez+vous+paris+online', 'online+appointment+hermes+paris', 'hermes+online+appointment+paris', 'paris+hermes+online+appointment'] 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}) } 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"); 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 } }) // this.page = pages[pages.length - 1]; // this.page = pages[0]; 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 { await this.device.shell("am start -n " + this.browserPackageName + "/com.google.android.apps.chrome.Main") await delay(5 * 1000); } catch (e) { console.log(e) this.isTerminated = true; } // Connect to the device. if (this.browser) { logWithDevice("browser.isConnected is " + this.browser.isConnected(), this.device); } try { logWithDevice("connecting to browser:" + this.port, this.device); while (this.browser === undefined || !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(); // this.page = pages[0]; this.page = await this.browser.newPage(); this.page.on("load", (loadedPage) => { this.onPageLoad(loadedPage); }) this.page.on("response", (response) => { this.onResponse(response) }) await delay(3 * 1000); } } catch (e) { logWithDevice("failed to connect to device", this.device) console.log(e) // await this.resetBrowser() await this.checkResultWithOcr() this.isTerminated = true } if (this.page !== undefined) { try { logWithDevice("will open google", this.device) if (!this.isTerminated) { const item = searchTexts[Math.floor(Math.random() * searchTexts.length)]; await this.page.goto("https://www.google.com/search?q=" + item + "&lr=lang_en", {timeout: 30 * 1000}); } // await this.page.goto(RDV_URL, {timeout: 90 * 1000}); } catch (e) { log(e) this.isTerminated = true } await this.acceptCookies(); await this.enableDisableAirPlanMode(); await delay(10 * 1000); await this.clickOnlineAppointment(); // await delay(2000); // if (!this.isTerminated) // await this.clickOnlineAppointment(); } else { this.isTerminated = true; } let cancel const intervalTask = setInterval(() => { if (this.isTerminated) { log(this.device.model() + ":request terminated, send cancel()"); // this.resetBrowser(); 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) } } // if (this.page.url() === RDV_URL) { // if (!this.isFillingFields) // await this.fillFields(this.page, false); // } } catch (e) { 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()) await this.clickValid(); this.isFillingFields = false } } } async clickValid() { logWithDevice("clickValid() called.", this.device); await delay(getRandomWaitTime()) try { if (!this.page.isClosed()) { if (!this.isTerminated && !this.page.isClosed()) { this.page.evaluate(() => { let element = document.getElementsByClassName("btn")[0]; if (typeof element !== 'undefined') document.getElementsByClassName("btn")[0].focus(); }) } await delay(getRandomWaitTime()) 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") { let cmd = `adb -s ${this.device.serial()} shell input touchscreen swipe 900 495 900 295` await exec(cmd); await delay(1000); } 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 deleteFromBlackList() { await this.mongoManager.removeFromBlackList(this.contact) } async getErrors() { logWithDevice("getErrors", this.device); await this.checkResultWithOcr(); if (this.page.url() === BLANK_URL) { this.isTerminated = true; } else { try { // let errorItem = this.page.locator("div.alert"); // if (errorItem) { // let errorContent = await errorItem.innerHTML(); // await this.handleError(errorContent); // } } catch (e) { log(e); } } } 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; // this.disconnectBrowser(); 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) 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) { checkResult = await this.ocrChecker.get_result(); } else { // await this.checkResultWithOcr() checkResult = OCRResult.TERMINAED this.isTerminated = true } }) await delay(10 * 1000) } switch (checkResult) { case OCRResult.TERMINAED: this.isTerminated = true; break; case OCRResult.SLIDING_CAPTCHA_REFRESH: await this.connect_to_browser(checkResult) break; case OCRResult.FILL_FIELD: // console.log("browser.isConnected: " + this.browser.isConnected()); 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 }) logWithDevice("get pages", this.device) let pages = await this.browser.pages(); // let needPages = pages.filter(currentPage => currentPage.url() === RDV_URL) // this.page = needPages[0] try { pages.forEach((currentPage) => { if (currentPage.url() === RDV_URL) { this.page = currentPage; } else { try { currentPage.close() } catch (e) { console.log(e) } } }) } catch (e) { this.isTerminated = true; 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) this.isTerminated = true } } else { logWithDevice("this.browser.isConnected() is " + this.browser.isConnected(), this.device) try { if (this.browser.isConnected()) { logWithDevice("get pages", this.device) let pages = await this.browser.pages(); logWithDevice("get current page", this.device) // let needPages = pages.filter(currentPage => currentPage.url() === RDV_URL) // this.page = needPages[0] try { pages.forEach((currentPage) => { if (currentPage.url() === RDV_URL) { this.page = currentPage; } else { // try { // if (!currentPage.isClosed()) { // currentPage.close() // } // } catch (e) { // console.log(e) // } } }) } catch (e) { this.isTerminated = true console.log(e) } 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: if (this.device.model() === "MI 5s") await this.device.shell("input tap " + 530 + " " + 970) else if (this.device.model() === "ONEPLUS A6000") await this.device.shell("input tap " + 530 + " " + 1064) else await this.device.shell("input tap " + 500 + " " + 1120) await delay(2000); await this.checkResultWithOcr(); break; case OCRResult.BRAVE_PRIVACY_PUB: if (this.device.model() === "MI 5s") await this.device.shell("input tap " + 60 + " " + 1400) else await this.device.shell("input tap " + 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.device.shell("input tap " + 540 + " " + 1611) else if (this.device.model() === "22041219PG") await this.device.shell("input tap " + 530 + " " + 1600) else await this.device.shell("input tap " + 500 + " " + 1680) await delay(2000); await this.checkResultWithOcr(); 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") { await this.device.shell("input tap " + 530 + " " + 1000) } else if (model === "ONEPLUS A6000") { await this.device.shell("input tap " + 530 + " " + 1106) } else { await this.device.shell("input tap " + 470 + " " + 1160) } await delay(2000); await this.device.shell("input tap " + 455 + " " + 1920) await delay(1000); } 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 this.device.shell("input tap " + 933 + " " + 1538) await delay(2000); } async closePage() { await this.resetBrowser(); // while (!this.browser.isConnected()) { // logWithDevice("trying to connect to browser", this.device) // this.browser = await puppeteer.connect({ // browserWSEndpoint: "ws://127.0.0.1:" + this.port + "/devtools/browser", // headless: false, defaultViewport: null // }) // await delay(2 * 1000); // } // console.log("will close all pages"); // let pages = await this.browser.pages(); // await pages[0].close() // console.log("page closed"); // pages.forEach((currentPage) => { // currentPage.close(); // }) // await this.browser.close(); } 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 this.device.shell("adb shell settings put global airplane_mode_on 1") await delay(1000) // await this.device.shell("adb shell settings put global airplane_mode_on 0") 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.device.shell("input tap " + 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() === "22041219PG") { await this.device.shell("input tap " + 411 + " " + 2020) } else await this.device.shell("input tap " + 411 + " " + 2100) } await delay(2000); } } module .exports = CommandorPage