@auxcode/auxta 0.4.4 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/AuxTA.ts +18 -8
- package/src/macros/helpers/code.helper.ts +63 -16
- package/src/puppeteer/puppeteer.ts +51 -9
package/package.json
CHANGED
package/src/AuxTA.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import puppeteer, {
|
|
2
|
-
import {
|
|
1
|
+
import puppeteer, {Puppeteer} from "./puppeteer/puppeteer";
|
|
2
|
+
import {FunctionHelper} from "./macros/helpers/code.helper";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import StatusOfStep from "./auxta/enums/status-of.step";
|
|
6
|
-
import {
|
|
6
|
+
import {UploadModel} from "./auxta/models/upload.model";
|
|
7
7
|
import * as dotenv from "dotenv";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import {setupConfig, config as c, setupOverrideConfig} from "./auxta/configs/config";
|
|
9
|
+
import {startSuite} from "./auxta/utilities/start-suite.helper";
|
|
10
|
+
import {createEmptyReport} from "./auxta/services/report.service";
|
|
11
11
|
|
|
12
12
|
dotenv.config();
|
|
13
13
|
|
|
@@ -41,7 +41,7 @@ class AuxTA extends FunctionHelper {
|
|
|
41
41
|
} catch (e) {
|
|
42
42
|
console.log("Missing field in auxta.json:", e)
|
|
43
43
|
}
|
|
44
|
-
this.uploadModel = new UploadModel(jsonConfig.organization, jsonConfig.baseURL, jsonConfig.digitalProduct,jsonConfig.environment);
|
|
44
|
+
this.uploadModel = new UploadModel(jsonConfig.organization, jsonConfig.baseURL, jsonConfig.digitalProduct, jsonConfig.environment);
|
|
45
45
|
} catch (e) {
|
|
46
46
|
console.log("Missing or corrupted config: auxta.json. Searching in location:", file)
|
|
47
47
|
console.log(e);
|
|
@@ -58,7 +58,8 @@ class AuxTA extends FunctionHelper {
|
|
|
58
58
|
await startSuite(suites, reportId || await createEmptyReport(this.uploadModel));
|
|
59
59
|
return {statusCode: 204}
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
private changeModelData(overrideConfig?: any) {
|
|
62
63
|
if (overrideConfig) {
|
|
63
64
|
if (overrideConfig.digitalProduct) this.uploadModel.digitalProduct = overrideConfig.digitalProduct
|
|
64
65
|
if (overrideConfig.environment) this.uploadModel.environment = overrideConfig.environment
|
|
@@ -78,6 +79,15 @@ class AuxTA extends FunctionHelper {
|
|
|
78
79
|
return this.puppeteer.run(event, callback, feature, scenario)
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
public async startBrowserRPA(event: any, callback: any, baseURL: string) {
|
|
83
|
+
this.changeModelData({
|
|
84
|
+
baseURL: baseURL,
|
|
85
|
+
environment: '',
|
|
86
|
+
digitalProduct: ''
|
|
87
|
+
});
|
|
88
|
+
return this.puppeteer.runRPA(event, callback)
|
|
89
|
+
}
|
|
90
|
+
|
|
81
91
|
public getUploadModel(): UploadModel {
|
|
82
92
|
return this.uploadModel;
|
|
83
93
|
}
|
|
@@ -6,22 +6,22 @@ import { config } from "../../auxta/configs/config";
|
|
|
6
6
|
export class FunctionHelper {
|
|
7
7
|
public readonly defaultTimeout: number = config.timeout;
|
|
8
8
|
|
|
9
|
-
public log(keyword: string, name: string, status: StatusOfStep){
|
|
9
|
+
public log(keyword: string, name: string, status: StatusOfStep) {
|
|
10
10
|
log.push(keyword, name, status)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
public suggest(name: string){
|
|
13
|
+
public suggest(name: string) {
|
|
14
14
|
log.addSuggestion(name)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
private getEscapedText(text: string){
|
|
17
|
+
private getEscapedText(text: string) {
|
|
18
18
|
const splitedQuotes = text.replace(/'/g, `', "'", '`)
|
|
19
19
|
return `concat('${splitedQuotes}', '')`;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
public async clickByText(selector: string, text: string, page = puppeteer.defaultPage, dotOrText = '.') {
|
|
23
23
|
const message = `I click on the '${text}' '${selector}'`;
|
|
24
|
-
try{
|
|
24
|
+
try {
|
|
25
25
|
const [linkHandlers] = await page.$x(`//${selector}[${dotOrText} = ${this.getEscapedText(text)}]`);
|
|
26
26
|
|
|
27
27
|
if (linkHandlers) {
|
|
@@ -29,15 +29,30 @@ export class FunctionHelper {
|
|
|
29
29
|
log.push('Then', message, StatusOfStep.PASSED);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
} catch (e){
|
|
32
|
+
} catch (e) {
|
|
33
33
|
}
|
|
34
34
|
log.push('Then', message, StatusOfStep.FAILED);
|
|
35
35
|
throw new Error(message);
|
|
36
36
|
}
|
|
37
|
+
public async clickByTextWithClass(class_selector: string, class_name: string, selector: string, text: string, page = puppeteer.defaultPage, dotOrText = '.') {
|
|
38
|
+
const message = `I click on the '${text}' '${selector}'`;
|
|
39
|
+
try {
|
|
40
|
+
const [linkHandlers] = await page.$x(`//${class_selector}[contains(@class,${this.getEscapedText(class_name)})]//${selector}[${dotOrText} = ${this.getEscapedText(text)}]`);
|
|
37
41
|
|
|
42
|
+
if (linkHandlers) {
|
|
43
|
+
await linkHandlers.click();
|
|
44
|
+
log.push('Then', message, StatusOfStep.PASSED);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
}
|
|
49
|
+
log.push('Then', message, StatusOfStep.FAILED);
|
|
50
|
+
throw new Error(message);
|
|
51
|
+
}
|
|
52
|
+
//div[contains(@class,"mat-menu-content")]//button
|
|
38
53
|
public async waitForSelectorWithText(selector: string, text: string, page = puppeteer.defaultPage, dotOrText = '.') {
|
|
39
54
|
const message = `I check for '${text}' on the current page`;
|
|
40
|
-
try{
|
|
55
|
+
try {
|
|
41
56
|
await page.waitForSelector(selector, {
|
|
42
57
|
timeout: this.defaultTimeout
|
|
43
58
|
});
|
|
@@ -46,7 +61,7 @@ export class FunctionHelper {
|
|
|
46
61
|
log.push('And', message, StatusOfStep.PASSED);
|
|
47
62
|
return true;
|
|
48
63
|
}
|
|
49
|
-
}catch (e) {
|
|
64
|
+
} catch (e) {
|
|
50
65
|
}
|
|
51
66
|
log.push('And', message, StatusOfStep.FAILED);
|
|
52
67
|
throw new Error(message);
|
|
@@ -58,7 +73,7 @@ export class FunctionHelper {
|
|
|
58
73
|
}
|
|
59
74
|
|
|
60
75
|
public async type(field: string, value: string, page = puppeteer.defaultPage) {
|
|
61
|
-
try{
|
|
76
|
+
try {
|
|
62
77
|
await page.waitForSelector(field, {
|
|
63
78
|
timeout: this.defaultTimeout
|
|
64
79
|
});
|
|
@@ -66,7 +81,7 @@ export class FunctionHelper {
|
|
|
66
81
|
let elementName = await page.$eval(field, (e) => e.textContent);
|
|
67
82
|
if (!elementName || elementName === ' ') elementName = field;
|
|
68
83
|
log.push('Then', `I type '${value}' into the '${elementName}' field`, StatusOfStep.PASSED);
|
|
69
|
-
} catch (e){
|
|
84
|
+
} catch (e) {
|
|
70
85
|
const msg = `I type '${value}' into the '${field}' field`
|
|
71
86
|
log.push('Then', msg, StatusOfStep.FAILED);
|
|
72
87
|
throw new Error(msg)
|
|
@@ -75,10 +90,10 @@ export class FunctionHelper {
|
|
|
75
90
|
|
|
76
91
|
public async waitForNetwork(page = puppeteer.defaultPage) {
|
|
77
92
|
let message = 'I wait for the page to load'
|
|
78
|
-
try{
|
|
93
|
+
try {
|
|
79
94
|
await page.waitForNetworkIdle();
|
|
80
95
|
log.push('Then', message, StatusOfStep.PASSED);
|
|
81
|
-
} catch (e){
|
|
96
|
+
} catch (e) {
|
|
82
97
|
log.push('Then', message, StatusOfStep.FAILED);
|
|
83
98
|
throw new Error(message)
|
|
84
99
|
}
|
|
@@ -99,14 +114,14 @@ export class FunctionHelper {
|
|
|
99
114
|
* @param log_message
|
|
100
115
|
*/
|
|
101
116
|
|
|
102
|
-
public async waitForSelector(option: string, selector: string, time: number = this.defaultTimeout, page = puppeteer.defaultPage,log_message = true) {
|
|
117
|
+
public async waitForSelector(option: string, selector: string, time: number = this.defaultTimeout, page = puppeteer.defaultPage, log_message = true) {
|
|
103
118
|
const message = `I check for the '${selector}' element to be ${option}`;
|
|
104
|
-
try{
|
|
119
|
+
try {
|
|
105
120
|
await page.waitForSelector(selector, {
|
|
106
121
|
[option]: true,
|
|
107
122
|
timeout: time
|
|
108
123
|
});
|
|
109
|
-
} catch (e){
|
|
124
|
+
} catch (e) {
|
|
110
125
|
if (log_message) {
|
|
111
126
|
log.push('And', message, StatusOfStep.FAILED);
|
|
112
127
|
}
|
|
@@ -118,7 +133,7 @@ export class FunctionHelper {
|
|
|
118
133
|
}
|
|
119
134
|
|
|
120
135
|
public async click(selector: string, logMessages = true, page = puppeteer.defaultPage) {
|
|
121
|
-
try{
|
|
136
|
+
try {
|
|
122
137
|
await page.waitForSelector(selector, {
|
|
123
138
|
timeout: this.defaultTimeout
|
|
124
139
|
});
|
|
@@ -126,7 +141,7 @@ export class FunctionHelper {
|
|
|
126
141
|
if (!elementName || elementName === ' ') elementName = selector;
|
|
127
142
|
await page.click(selector);
|
|
128
143
|
log.push('Then', `I click on the '${elementName}'`, StatusOfStep.PASSED);
|
|
129
|
-
} catch (e){
|
|
144
|
+
} catch (e) {
|
|
130
145
|
const msg = `I click on the '${selector}'`;
|
|
131
146
|
log.push('Then', msg, StatusOfStep.FAILED);
|
|
132
147
|
throw new Error(msg)
|
|
@@ -143,6 +158,38 @@ export class FunctionHelper {
|
|
|
143
158
|
log.push('And', message, StatusOfStep.PASSED);
|
|
144
159
|
}
|
|
145
160
|
|
|
161
|
+
public async pressEnter(page = puppeteer.defaultPage) {
|
|
162
|
+
await page.keyboard.press('Enter');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//TODO work in progress
|
|
166
|
+
/*
|
|
167
|
+
private async microsoftLogin(button: string, email: string, password: string) {
|
|
168
|
+
const email_input = 'input[type="email"]';
|
|
169
|
+
const password_input = 'input[type="password"]';
|
|
170
|
+
const no_button = 'input[type="button"]';
|
|
171
|
+
// click on login button
|
|
172
|
+
const nav = new Promise(res => puppeteer.defaultPage.browser().on('targetcreated', res));
|
|
173
|
+
await this.click(button);
|
|
174
|
+
await nav;
|
|
175
|
+
const pages = await puppeteer.defaultPage.browser().pages();
|
|
176
|
+
const loginPage = pages[pages.length - 1];
|
|
177
|
+
// enter password and submit
|
|
178
|
+
await this.waitForSelector('visible', email_input, 60000, loginPage);
|
|
179
|
+
await this.type(email_input, email, loginPage);
|
|
180
|
+
await this.pressEnter(loginPage);
|
|
181
|
+
await this.waitForNetwork(loginPage);
|
|
182
|
+
// enter password and submit
|
|
183
|
+
await this.waitForSelector('visible', password_input, 60000, loginPage);
|
|
184
|
+
await this.type(password_input, password, loginPage);
|
|
185
|
+
await this.pressEnter(loginPage);
|
|
186
|
+
await this.waitForNetwork(loginPage);
|
|
187
|
+
// press no
|
|
188
|
+
await this.waitForSelector('visible', no_button, 60000, loginPage);
|
|
189
|
+
await this.click(no_button, true, loginPage);
|
|
190
|
+
await this.waitForNetwork(loginPage);
|
|
191
|
+
}*/
|
|
192
|
+
|
|
146
193
|
}
|
|
147
194
|
|
|
148
195
|
export default new FunctionHelper();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import chromium from 'chrome-aws-lambda';
|
|
2
2
|
import log from "../auxta/services/log.service";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {captureScreenshot} from "../auxta/utilities/screenshot.helper";
|
|
4
|
+
import {onTestEnd} from "../auxta/hooks/report.hook";
|
|
5
5
|
import auxta from "../AuxTA";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import {StatusOfStep} from "../auxta/enums/status-of.step";
|
|
7
|
+
import {UploadModel} from "../auxta/models/upload.model";
|
|
8
8
|
import puppeteer_core from 'puppeteer-core';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import {config} from "./../auxta/configs/config";
|
|
10
|
+
import {postNotificationsOnFail} from "../auxta/services/report.service";
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
export class Puppeteer {
|
|
@@ -16,7 +16,11 @@ export class Puppeteer {
|
|
|
16
16
|
|
|
17
17
|
public async startBrowser() {
|
|
18
18
|
let args = [
|
|
19
|
-
'--start-maximized'
|
|
19
|
+
'--start-maximized',
|
|
20
|
+
'--no-sandbox',
|
|
21
|
+
'--disable-setuid-sandbox',
|
|
22
|
+
'--disable-dev-shm-usage',
|
|
23
|
+
'--single-process'
|
|
20
24
|
];
|
|
21
25
|
if (process.env.ENVIRONMENT != 'LOCAL')
|
|
22
26
|
args.push(`--window-size=${config.screenWidth},${config.screenHeight}`)
|
|
@@ -45,7 +49,7 @@ export class Puppeteer {
|
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
public async run(event: any, callback: any, featureName = 'Test feature', scenarioName = 'Test scenario', uploadModel?: UploadModel, close?: boolean) {
|
|
48
|
-
try{
|
|
52
|
+
try {
|
|
49
53
|
if (uploadModel === undefined) uploadModel = auxta.getUploadModel();
|
|
50
54
|
if (close === undefined) close = Puppeteer.setupHeader(event, uploadModel)
|
|
51
55
|
let screenshotBuffer: Buffer | undefined;
|
|
@@ -81,13 +85,51 @@ export class Puppeteer {
|
|
|
81
85
|
console: consoleStack,
|
|
82
86
|
error: errMessage
|
|
83
87
|
});
|
|
84
|
-
} catch (e){
|
|
88
|
+
} catch (e) {
|
|
85
89
|
console.log("Lib error:", e);
|
|
86
90
|
} finally {
|
|
87
91
|
log.clear();
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
95
|
+
public async runRPA(event: any, callback: any, close?: boolean) {
|
|
96
|
+
let errMessage: any;
|
|
97
|
+
try {
|
|
98
|
+
if (close === undefined) {
|
|
99
|
+
if (event.queryStringParameters.close) {
|
|
100
|
+
close = event.queryStringParameters.close === "true";
|
|
101
|
+
} else {
|
|
102
|
+
close = true
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
let consoleStack: any[] = [];
|
|
106
|
+
try {
|
|
107
|
+
await log.push('When', `Starting puppeteer process`, StatusOfStep.PASSED);
|
|
108
|
+
await this.startBrowser()
|
|
109
|
+
this.defaultPage.on('console', message =>
|
|
110
|
+
consoleStack.push(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`))
|
|
111
|
+
.on('pageerror', ({message}) => consoleStack.push(message))
|
|
112
|
+
.on('response', response =>
|
|
113
|
+
consoleStack.push(`${response.status()} ${response.url()}`))
|
|
114
|
+
.on('requestfailed', request =>
|
|
115
|
+
consoleStack.push(`${request.failure() !== null ? request.failure()?.errorText : ""} ${request.url()}`))
|
|
116
|
+
await callback(event)
|
|
117
|
+
log.push('When', `Finished puppeteer process`, StatusOfStep.PASSED);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.log("Error", err);
|
|
120
|
+
errMessage = err;
|
|
121
|
+
log.push('When', `Finished puppeteer process`, StatusOfStep.FAILED);
|
|
122
|
+
return errMessage;
|
|
123
|
+
}
|
|
124
|
+
if (close) await this.close();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.log("Lib error:", e);
|
|
127
|
+
} finally {
|
|
128
|
+
log.clear();
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
91
133
|
private static setupHeader(event: any, uploadModel: UploadModel) {
|
|
92
134
|
let close = true;
|
|
93
135
|
if (process.env.ENVIRONMENT !== 'LOCAL' && event.body) {
|