Skip to content

Commit

Permalink
Gorilla001 (#238)
Browse files Browse the repository at this point in the history
* gorilla

* sample gorilla

* members

* labler
  • Loading branch information
hajonsoft authored Jan 4, 2025
1 parent c55f2aa commit da41766
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 69 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hajonsoft-eagle",
"version": "2.6.44",
"version": "2.7.0",
"description": "HAJonSoft node app to submit passengers to visa systems",
"main": "index.js",
"scripts": {
Expand Down
20 changes: 20 additions & 0 deletions src/lib/kea.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ const init = async () => {
console.log("Captcha key found in database");
}

// Gorilla is the package selection configuration. it looks like this
const gorillaSample = {
enabled: true,
accounts: ['tuTskCqZJBXtYWmPu7MufF','tuTskCqZJBXtYWmPu7MufF'],
goto: 'https://nusuk.hajj.sa/packages/selected/',
actions: [
{
selector: '#controlID',
wait: true,
click: false,
}
]
}
global.gorilla = null;
const gorillaSnapshot = await get(dbRef(database, "app-data/gorilla"));
if (gorillaSnapshot.exists()) {
global.gorilla = gorillaSnapshot.val();
console.log("Gorilla code found in database");
}

await getSubmission(submissionId);

if (!runId) {
Expand Down
20 changes: 20 additions & 0 deletions src/lib/labeler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export async function labeler(page, additionalValue, selector) {
// Get the innerText of the specified selector
const originalText = await page.$eval(selector, (el) => el.innerText);

// Combine the original text with the additional value
const updatedText = `${originalText} ${additionalValue}`;

// Update the innerText of the specified selector
await page.$eval(
selector,
(el, newText) => {
el.innerText = newText;
},
updatedText
);

// Return the updated text for reference
return updatedText;
}

132 changes: 64 additions & 68 deletions src/nsh.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const childProcess = require("child_process");
const sharp = require("sharp");
const registerCaptchaAbortController = new AbortController();
const loginCaptchaAbortController = new AbortController();
const { labeler } = require('./lib/labeler')


let page;
Expand Down Expand Up @@ -47,7 +48,7 @@ const URLS = {
PREFERENCES_YOURS: "https://hajj.nusuk.sa/Registration/Preferences/yours/[0-9a-f-]+",
REGISTRATION_SUMMARY: "https://hajj.nusuk.sa/registration/summary/[0-9a-f-]+",
SUCCESS: "https://hajj.nusuk.sa/Registration/Success",
MEMBERS: "https://hajj.nusuk.sa/profile/members",
MEMBERS: "https://hajj.nusuk.sa/profile/myfamily/members",
SIGNOUT: "https://hajj.nusuk.sa/Account/Signout",
};

Expand Down Expand Up @@ -296,11 +297,16 @@ async function onContentLoaded(res) {
}
}

// TODO: Refactor instead of a big switch case, see what other options you could utilize.
async function pageContentHandler(currentConfig) {
const passenger = data.travellers[util.getSelectedTraveler()];
// TODO: Create configHandler function that checks if there is a controller and execute it, if screen shot is expected,
// if a scroll is expected
if (currentConfig.controller) {
await util.controller(page, currentConfig, data.travellers);
}
switch (currentConfig.name) {
case "home":
await util.controller(page, currentConfig, data.travellers);
const leads = data.travellers.filter(
(traveller) =>
!traveller.isCompanion &&
Expand All @@ -323,15 +329,14 @@ async function pageContentHandler(currentConfig) {
},
});
}

if (process.argv.includes("--auto")) {
if (passenger.email?.includes(".companion") || passenger.isCompanion) {
if (global.headless) {
if (passenger.isCompanion) {
console.log("can not login as a companion")
await page.browser().close();
} else {
await loginOrRegister("0");
return;
}
} else if (global.headless) {
await loginOrRegister("0");
await loginOrRegister(util.getSelectedTraveler());
return;
}
break;
case "index":
Expand Down Expand Up @@ -368,7 +373,6 @@ async function pageContentHandler(currentConfig) {
if (!manualMode) {
manualMode = currentConfig.name;
}
await util.controller(page, currentConfig, data.travellers);
if (fs.existsSync(getPath("loop.txt"))) {
await signup_step1(util.getSelectedTraveler());
}
Expand Down Expand Up @@ -441,7 +445,6 @@ async function pageContentHandler(currentConfig) {
if (!manualMode) {
manualMode = currentConfig.name;
}
await util.controller(page, currentConfig, data.travellers);
await util.commander(page, {
controller: {
selector:
Expand Down Expand Up @@ -486,8 +489,7 @@ async function pageContentHandler(currentConfig) {
});
util.incrementSelectedTraveler();
}
await util.controller(page, currentConfig, data.travellers);
completeRegistration(util.getSelectedTraveler());
await completeRegistration(util.getSelectedTraveler());
break;
case "contact":
// review telephone number
Expand Down Expand Up @@ -593,7 +595,6 @@ async function pageContentHandler(currentConfig) {
);
break;
case "summary":
await util.controller(page, currentConfig, data.travellers);
if (passenger.nationality.code !== data.system.country.code) {
await summaryResidence(util.getSelectedTraveler());
} else {
Expand Down Expand Up @@ -698,8 +699,6 @@ async function pageContentHandler(currentConfig) {
);
break;
case "upload-documents":
await util.controller(page, currentConfig, data.travellers);

// Close the modal by clicking this element if it is in the DOM
const documentGuideSelector =
"#uploadDocumentsGuide > div > div > div > div.d-flex.align-items-center.justify-content-between > span";
Expand Down Expand Up @@ -734,11 +733,6 @@ async function pageContentHandler(currentConfig) {
util.clickWhenReady("#HaveValidResidencyNo", page);
break;
case "login":
if (global.headless) {
await page.browser().close();
process.exit(0);
return;
}
clearTimeout(timerHandler);
await closeAccountCreatedSuccessModal();
await page.$eval(
Expand All @@ -763,7 +757,6 @@ async function pageContentHandler(currentConfig) {
if (fs.existsSync(getPath("loop.txt"))) {
await loginPassenger(util.getSelectedTraveler());
}
await util.controller(page, currentConfig, data.travellers);

await loginPassenger(util.getSelectedTraveler());
break;
Expand All @@ -778,7 +771,6 @@ async function pageContentHandler(currentConfig) {
}, 10000);
break;
case "members":
await util.controller(page, currentConfig, data.travellers);
break;
case "signout":
util.incrementSelectedTraveler();
Expand Down Expand Up @@ -824,6 +816,7 @@ function suggestPhoneNumber(selectedTraveler) {
}
}

// TODO: Make it accept an array and recall itself in case of array. paralleize when possible
async function checkIfNotChecked(selector) {
try {
const isChecked = await page.$eval(selector, (el) => el.checked);
Expand Down Expand Up @@ -1580,53 +1573,14 @@ async function completeRegistration(selectedTraveler) {
passenger
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(11) > div > div.col-md-6.font-semibold.align-self-center",
(el, birthPlace) => (el.innerText = `Birth Place: ${birthPlace}`),
passenger.birthPlace
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(16) > div > div.col-md-6.font-semibold.align-self-center",
(el, issueDate) => (el.innerText = `Issue Date: ${issueDate}`),
passenger.passIssueDt.dmmmy
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(10) > div > div.col-md-6.font-semibold.align-self-center",
(el, birthDate) => (el.innerText = `Birth Date: ${birthDate}`),
passenger.dob.dmmmy
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(9) > div > div.col-md-6.font-semibold.align-self-center",
(el, nationality) => (el.innerText = `Nationality: ${nationality}`),
passenger.nationality.name
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(12) > div > div.col-md-6.font-semibold.align-self-center",
(el, gender) => (el.innerText = `Gender: ${gender}`),
passenger.gender
);

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(17) > div > div.col-md-6.font-semibold.align-self-center",
(el, expireDate) => (el.innerText = `Expire Date: ${expireDate}`),
passenger.passExpireDt.dmmmy
);
await labeler(page, passenger.dob.dmmmy, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(11) > div > div.col-md-6.font-semibold.align-self-center")
await labeler(page, passenger.gender, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(13) > div > div.col-md-6.font-semibold.align-self-center")
await labeler(page, passenger.passportNumber, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(15) > div > div.col-md-6.font-semibold.align-self-center")

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(14) > div > div.col-md-6.font-semibold.align-self-center",
(el, passportNumber) => (el.innerText = `Passport No: ${passportNumber}`),
passenger.passportNumber
);
await labeler(page, passenger.passIssueDt.dmmmy, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(17) > div > div.col-md-6.font-semibold.align-self-center")
await labeler(page, passenger.passExpireDt.dmmmy, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(18) > div > div.col-md-6.font-semibold.align-self-center")
await labeler(page, passenger.placeOfIssue, "#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(16) > div > div.col-md-6.font-semibold.align-self-center")

await page.$eval(
"#summary-from > div.system-content.p-3 > div.d-flex.flex-column-reverse.flex-lg-row.mb-5 > div.col-xl-9.col-lg-8 > div:nth-child(1) > ul > li:nth-child(15) > div > div.col-md-6.font-semibold.align-self-center",
(el, issuePlace) => (el.innerText = `Issue Place: ${issuePlace}`),
passenger.placeOfIssue
);

kea.updatePassenger(data.system.accountId, passenger.passportNumber, {
"submissionData.nsh.status": "Submitted",
Expand Down Expand Up @@ -1694,4 +1648,46 @@ async function runParallel() {
await page.browser().close();
}

async function executeGorilla() {
const gorilla = global.gorilla;
if (!gorilla || !gorilla.enabled) {
return;
}

if (!gorilla.accounts?.find(a => a === data.system.accountId)) {
return;
}

if (gorilla.goto) {
await page.goto(gorilla.goto)
}

for (const action of gorilla.actions) {
if (action.wait) {
await page.waitForSelector(action.selector)
}
if (action.click) {
await page.click(action.selector)
}
}
}

module.exports = { send };


// TODO: Gorilla
// 1- After logging succesfully
// 2- Check which page the passenger lands in and check the following
// - the passenger has been registered succesfully
// - There is gorilla script
// - this user account is in the gorilla accounts
// - start executing the gorilla
// TODO: Refactor opprtunities
// 1- Create a common function for all page views to install the controller or any commanders asynchronously when not headless
// 2- modularize the code on seaparate files
// 3- handle errors and retries to gurantee registration
// 4- implement new captcha mouse click
// 5- add scroll to element in config and scroll to it
// TODO: Chunk-ing
// 1- Take all the travellers and divide them into leader and its companions
// 2- for each leader and the associated companion get a machine to register them

0 comments on commit da41766

Please sign in to comment.