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;
step: GBDialogStep;
public async getDeployer() {
return this.min.deployService;
}
@ -124,8 +124,8 @@ export class DialogKeywords {
*
* @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) {
this.browser = await puppeteer.launch({
args: [
@ -138,8 +138,14 @@ export class DialogKeywords {
ignoreHTTPSErrors: true,
headless: false,
});
// set the HTTP Basic Authentication credential
}
const page = await this.browser.newPage();
if (username || password) {
await page.authenticate({ 'username': username, 'password': password });
}
await page.goto(url);
return page;
}
@ -237,12 +243,24 @@ export class DialogKeywords {
/**
* Find element on page DOM.
*
* @example GET page, "elementName", "text"
* @example GET page, "elementName"
*/
public async getBySelector(page, elementName) {
GBLog.info(`BASIC: Web Automation GET element: ${elementName}.`);
await page.waitForSelector(elementName)
let element = await page.$(elementName);
return element;
let elements = await page.$$(elementName);
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"
*/
public async getByFrame(page, frame, selector) {
GBLog.info(`BASIC: Web Automation GET element by frame: ${selector}.`);
await page.waitForSelector(frame)
let frameHandle = await page.$(frame);
const f = await frameHandle.contentFrame();
await f.waitForSelector(selector);
const element = await f.$(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;
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
*/
public async click(step, page, idOrName) {
const e = await this.getBySelector(page, idOrName);
await Promise.all([
page.waitForNavigation(),
page.click(e.name)
]);
public async click(step, page, frameOrSelector, selector) {
GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (selector) {
await page.waitForSelector(frameOrSelector)
let frameHandle = await page.$(frameOrSelector);
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
*/
public async screenshot(step, page, idOrName, localName) {
GBLog.info(`BASIC: Web Automation SCREENSHOT ${idOrName}.`);
const e = await this.getBySelector(page, idOrName);
await e.screenshot({ path: localName });
}
@ -296,8 +343,9 @@ export class DialogKeywords {
* @example TYPE page, "elementName", "text"
*/
public async type(step, page, idOrName, text) {
GBLog.info(`BASIC: Web Automation TYPE on ${idOrName}: ${text}.`);
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
*/
public async getOCR(step, localFile) {
GBLog.info(`BASIC: OCR processing on ${localFile}.`);
const tesseract = require("node-tesseract-ocr")
const config = {
@ -407,12 +456,11 @@ export class DialogKeywords {
}
public getCoded(value){
public getCoded(value) {
// Checks if it is a GB FILE object.
if (value.data && value.filename)
{
if (value.data && value.filename) {
value = value.data;
}
@ -687,6 +735,21 @@ export class DialogKeywords {
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.
*

View file

@ -324,41 +324,41 @@ export class GBVMService extends GBService {
});
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) => {
return ` = {}`;
});
code = code.replace(/\= NEW ARRAY/gi, ($0, $1, $2, $3) => {
return ` = []`;
});
code = code.replace(/(go to)(\s)(.*)/gi, ($0, $1, $2, $3) => {
return `gotoDialog(step, ${$3})\n`;
@ -392,6 +392,10 @@ export class GBVMService extends GBService {
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) => {
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) => {
return `sendEmail (${$3})\n`;
});
code = code.replace(/(send file to)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
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) => {
return `click (step, ${$3})\n`;
});
@ -745,10 +757,16 @@ export class GBVMService extends GBService {
code = code.replace(/("[^"]*"|'[^']*')|\bclick\b/gi, ($0, $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) => {
return $1 === undefined ? 'this.sendEmail' : $1;
});
// await insertion.
// await insertion.
code = code.replace(/this\./gm, 'await this.');
code = code.replace(/\nfunction/i, 'async function');

View file

@ -422,7 +422,7 @@ export class SystemKeywords {
*/
public async wait(seconds: number) {
// 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));
await timeout(seconds * 1000);
}
@ -575,15 +575,18 @@ export class SystemKeywords {
}
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];
if (value && this.isValidDate(value)) {
value = `'${value}`;
}
body.values[0][index] = value;
}
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);
}

View file

@ -988,7 +988,7 @@ export class GBMinService {
user.subjects = [];
user.cb = undefined;
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;