new(basic.gblib): WEb Automation HOVER and LINK BY TEXT keywords.

This commit is contained in:
Rodrigo Rodriguez 2022-08-26 09:53:00 -03:00
parent ee5b9a7567
commit f5826e1f0d
5 changed files with 127 additions and 42 deletions

1
gbot.sh Executable file
View file

@ -0,0 +1 @@
node .

View file

@ -86,7 +86,7 @@ export class DialogKeywords {
hrOn: string; hrOn: string;
step: GBDialogStep; step: GBDialogStep;
public async getDeployer() { public async getDeployer() {
return this.min.deployService; return this.min.deployService;
} }
@ -124,8 +124,8 @@ export class DialogKeywords {
* *
* @example x = GET PAGE * @example x = GET PAGE
*/ */
public async getPage(step, url) { public async getPage(step, url, username, password) {
GBLog.info(`BASIC: Web Automation GET PAGE ${url}.`);
if (!this.browser) { if (!this.browser) {
this.browser = await puppeteer.launch({ this.browser = await puppeteer.launch({
args: [ args: [
@ -138,8 +138,14 @@ export class DialogKeywords {
ignoreHTTPSErrors: true, ignoreHTTPSErrors: true,
headless: false, headless: false,
}); });
// set the HTTP Basic Authentication credential
} }
const page = await this.browser.newPage(); const page = await this.browser.newPage();
if (username || password) {
await page.authenticate({ 'username': username, 'password': password });
}
await page.goto(url); await page.goto(url);
return page; return page;
} }
@ -237,12 +243,24 @@ export class DialogKeywords {
/** /**
* Find element on page DOM. * Find element on page DOM.
* *
* @example GET page, "elementName", "text" * @example GET page, "elementName"
*/ */
public async getBySelector(page, elementName) { public async getBySelector(page, elementName) {
GBLog.info(`BASIC: Web Automation GET element: ${elementName}.`);
await page.waitForSelector(elementName) await page.waitForSelector(elementName)
let element = await page.$(elementName); let elements = await page.$$(elementName);
return element; if (elements && elements.length > 1) {
return elements;
}
else {
const el = elements[0];
el['originalSelector'] = elementName;
el['href'] = await page.evaluate(e => e.getAttribute('href'), el);
el['value'] = await page.evaluate(e => e.getAttribute('value'), el);
el['name'] = await page.evaluate(e => e.getAttribute('name'), el);
el['class'] = await page.evaluate(e => e.getAttribute('class'), el);
return el;
}
} }
/** /**
@ -251,31 +269,59 @@ export class DialogKeywords {
* @example GET page, "frameSelector, "elementSelector" * @example GET page, "frameSelector, "elementSelector"
*/ */
public async getByFrame(page, frame, selector) { public async getByFrame(page, frame, selector) {
GBLog.info(`BASIC: Web Automation GET element by frame: ${selector}.`);
await page.waitForSelector(frame) await page.waitForSelector(frame)
let frameHandle = await page.$(frame); let frameHandle = await page.$(frame);
const f = await frameHandle.contentFrame(); const f = await frameHandle.contentFrame();
await f.waitForSelector(selector); await f.waitForSelector(selector);
const element = await f.$(selector); const element = await f.$(selector);
element['originalSelector'] = selector; element['originalSelector'] = selector;
element['href'] = await f.evaluate(e => e.getAttribute('href'), element);
element['value'] = await f.evaluate(e => e.getAttribute('value'), element);
element['name'] = await f.evaluate(e => e.getAttribute('name'), element);
element['class'] = await f.evaluate(e => e.getAttribute('class'), element);
element['frame'] = f; element['frame'] = f;
return element; return element;
} }
/** /**
* Returns the today data filled in dd/mm/yyyy or mm/dd/yyyy. * Simulates a mouse hover an web page element.
*/
public async hover(step, page, idOrName) {
GBLog.info(`BASIC: Web Automation HOVER element: ${idOrName}.`);
await this.getBySelector(page, idOrName);
await page.hover(idOrName);
}
/**
* Clicks on an element in a web page.
* *
* @example x = TODAY * @example x = TODAY
*/ */
public async click(step, page, idOrName) { public async click(step, page, frameOrSelector, selector) {
const e = await this.getBySelector(page, idOrName); GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (selector) {
await Promise.all([ await page.waitForSelector(frameOrSelector)
page.waitForNavigation(), let frameHandle = await page.$(frameOrSelector);
page.click(e.name) const f = await frameHandle.contentFrame();
]); await f.waitForSelector(selector);
await f.click(selector);
}
else {
await page.waitForSelector(frameOrSelector);
await page.click(frameOrSelector);
}
} }
public async linkByText(step, page, text, index) {
GBLog.info(`BASIC: Web Automation CLICK LINK TEXT: ${text} ${index}.`);
if (!index) {
index = 1
}
const els = await page.$x(`//a[contains(., '${text}')]`);
await els[index - 1].click();
}
@ -285,6 +331,7 @@ export class DialogKeywords {
* @example file = SCREENSHOT page * @example file = SCREENSHOT page
*/ */
public async screenshot(step, page, idOrName, localName) { public async screenshot(step, page, idOrName, localName) {
GBLog.info(`BASIC: Web Automation SCREENSHOT ${idOrName}.`);
const e = await this.getBySelector(page, idOrName); const e = await this.getBySelector(page, idOrName);
await e.screenshot({ path: localName }); await e.screenshot({ path: localName });
} }
@ -296,8 +343,9 @@ export class DialogKeywords {
* @example TYPE page, "elementName", "text" * @example TYPE page, "elementName", "text"
*/ */
public async type(step, page, idOrName, text) { public async type(step, page, idOrName, text) {
GBLog.info(`BASIC: Web Automation TYPE on ${idOrName}: ${text}.`);
const e = await this.getBySelector(page, idOrName); const e = await this.getBySelector(page, idOrName);
await e.type(text); await e.type(text, { delay: 200 });
} }
/** /**
@ -306,6 +354,7 @@ export class DialogKeywords {
* @example x = TODAY * @example x = TODAY
*/ */
public async getOCR(step, localFile) { public async getOCR(step, localFile) {
GBLog.info(`BASIC: OCR processing on ${localFile}.`);
const tesseract = require("node-tesseract-ocr") const tesseract = require("node-tesseract-ocr")
const config = { const config = {
@ -407,12 +456,11 @@ export class DialogKeywords {
} }
public getCoded(value){ public getCoded(value) {
// Checks if it is a GB FILE object. // Checks if it is a GB FILE object.
if (value.data && value.filename) if (value.data && value.filename) {
{
value = value.data; value = value.data;
} }
@ -687,6 +735,21 @@ export class DialogKeywords {
this.user = user; this.user = user;
} }
/**
* Defines the maximum lines to scan in spreedsheets.
*
* @example SET MAX COLUMNS 5000
*
*/
public async setMaxColumns(step, count) {
const user = await this.min.userProfile.get(step.context, {});
user.basicOptions.maxColumns = count;
await this.min.userProfile.set(step.context, user);
this.user = user;
}
/** /**
* Defines the FIND behaviour to consider whole words while searching. * Defines the FIND behaviour to consider whole words while searching.
* *

View file

@ -324,41 +324,41 @@ export class GBVMService extends GBService {
}); });
code = code.replace(/(\w+)\s*\=\s*get\s(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(\w+)\s*\=\s*get\s(.*)/gi, ($0, $1, $2, $3) => {
const count = ($2.match(/\,/g) || []).length;
const values = $2.split(',');
// Handles GET page, "selector". const count = ($2.match(/\,/g) || []).length;
const values = $2.split(',');
if (count == 1) { // Handles GET page, "selector".
return `${$1} = this.getByIDOrName(${values[0]}, ${values[1]} )`; if (count == 1) {
}
// Handles GET page, "frameSelector", "selector" return `${$1} = this.getBySelector(${values[0]}, ${values[1]} )`;
}
else if (count == 2) { // Handles GET page, "frameSelector", "selector"
return `${$1} = this.getByFrame(${values[0]}, ${values[1]}, ${values[2]} )`; else if (count == 2) {
}
// Handles the GET http version. return `${$1} = this.getByFrame(${values[0]}, ${values[1]}, ${values[2]} )`;
}
else { // Handles the GET http version.
else {
return `${$1} = sys().get (${$2}, headers)`;
}
return `${$1} = sys().get (${$2}, headers)`;
}
}); });
code = code.replace(/\= NEW OBJECT/gi, ($0, $1, $2, $3) => { code = code.replace(/\= NEW OBJECT/gi, ($0, $1, $2, $3) => {
return ` = {}`; return ` = {}`;
}); });
code = code.replace(/\= NEW ARRAY/gi, ($0, $1, $2, $3) => { code = code.replace(/\= NEW ARRAY/gi, ($0, $1, $2, $3) => {
return ` = []`; return ` = []`;
}); });
code = code.replace(/(go to)(\s)(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(go to)(\s)(.*)/gi, ($0, $1, $2, $3) => {
return `gotoDialog(step, ${$3})\n`; return `gotoDialog(step, ${$3})\n`;
@ -392,6 +392,10 @@ export class GBVMService extends GBService {
return `setMaxLines (step, ${$3})\n`; return `setMaxLines (step, ${$3})\n`;
}); });
code = code.replace(/(set max columns)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `setMaxColumns (step, ${$3})\n`;
});
code = code.replace(/(set translator)(\s*)(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(set translator)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`; return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`;
}); });
@ -467,11 +471,19 @@ export class GBVMService extends GBService {
code = code.replace(/(send mail)(\s*)(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(send mail)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `sendEmail (${$3})\n`; return `sendEmail (${$3})\n`;
}); });
code = code.replace(/(send file to)(\s*)(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(send file to)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `sendFileTo (step, ${$3})\n`; return `sendFileTo (step, ${$3})\n`;
}); });
code = code.replace(/(hover)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `hover (step, ${$3})\n`;
});
code = code.replace(/(click link text)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `linkByText (step, ${$3})\n`;
});
code = code.replace(/(click)(\s*)(.*)/gi, ($0, $1, $2, $3) => { code = code.replace(/(click)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `click (step, ${$3})\n`; return `click (step, ${$3})\n`;
}); });
@ -745,10 +757,16 @@ export class GBVMService extends GBService {
code = code.replace(/("[^"]*"|'[^']*')|\bclick\b/gi, ($0, $1) => { code = code.replace(/("[^"]*"|'[^']*')|\bclick\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.click' : $1; return $1 === undefined ? 'this.click' : $1;
}); });
code = code.replace(/("[^"]*"|'[^']*')|\blinkByText\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.linkByText' : $1;
});
code = code.replace(/("[^"]*"|'[^']*')|\bhover\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.hover' : $1;
});
code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/gi, ($0, $1) => { code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.sendEmail' : $1; return $1 === undefined ? 'this.sendEmail' : $1;
}); });
// await insertion. // await insertion.
code = code.replace(/this\./gm, 'await this.'); code = code.replace(/this\./gm, 'await this.');
code = code.replace(/\nfunction/i, 'async function'); code = code.replace(/\nfunction/i, 'async function');

View file

@ -422,7 +422,7 @@ export class SystemKeywords {
*/ */
public async wait(seconds: number) { public async wait(seconds: number) {
// tslint:disable-next-line no-string-based-set-timeout // tslint:disable-next-line no-string-based-set-timeout
GBLog.info(`BASIC: Talking to a specific user (TALK TO).`); GBLog.info(`BASIC: WAIT for ${seconds} second(s).`);
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
await timeout(seconds * 1000); await timeout(seconds * 1000);
} }
@ -575,15 +575,18 @@ export class SystemKeywords {
} }
let body = { values: [[]] }; let body = { values: [[]] };
for (let index = 0; index < 128; index++) {
const address = `A2:${this.numberToLetters(args.length - 1)}2`;
for (let index = 0; index < args.length; index++) {
let value = args[index]; let value = args[index];
if (value && this.isValidDate(value)) { if (value && this.isValidDate(value)) {
value = `'${value}`; value = `'${value}`;
} }
body.values[0][index] = value; body.values[0][index] = value;
} }
await client await client
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A2:DX2')`) .api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`)
.patch(body); .patch(body);
} }

View file

@ -988,7 +988,7 @@ export class GBMinService {
user.subjects = []; user.subjects = [];
user.cb = undefined; user.cb = undefined;
user.welcomed = false; user.welcomed = false;
user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true, theme: "white" }; user.basicOptions = { maxLines: 100, translatorOn: true, wholeWord: true, theme: "white", maxColumns: 40 };
firstTime = true; firstTime = true;