@kogeet/sagent-playwright 0.1.0
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/bin/core/Core.d.ts +61 -0
- package/bin/core/Core.d.ts.map +1 -0
- package/bin/core/Core.js +108 -0
- package/bin/core/LocatorLib.d.ts +4 -0
- package/bin/core/LocatorLib.d.ts.map +1 -0
- package/bin/core/LocatorLib.js +135 -0
- package/bin/index.d.ts +3 -0
- package/bin/index.d.ts.map +1 -0
- package/bin/index.js +16 -0
- package/bin/libs/BrowserLib.d.ts +19 -0
- package/bin/libs/BrowserLib.d.ts.map +1 -0
- package/bin/libs/BrowserLib.js +220 -0
- package/bin/libs/StdLib.d.ts +75 -0
- package/bin/libs/StdLib.d.ts.map +1 -0
- package/bin/libs/StdLib.js +234 -0
- package/package.json +38 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Page } from "playwright";
|
|
2
|
+
import { chromium, firefox, webkit } from "playwright";
|
|
3
|
+
import type { BrowserContextOptions } from "playwright-core";
|
|
4
|
+
type Navigator = typeof chromium | typeof firefox | typeof webkit;
|
|
5
|
+
declare class CoreBrowser {
|
|
6
|
+
private browser;
|
|
7
|
+
private ctx;
|
|
8
|
+
private idxActivePage;
|
|
9
|
+
/**
|
|
10
|
+
* **Launch browser and retrieve appropriate context**
|
|
11
|
+
* @param navig chromium or firefox or webkit
|
|
12
|
+
* @param device kind of device (ex : iPhone11, Desktop Firefox, ...)
|
|
13
|
+
* @param channel required for some devices : chrome or firefox or msedge
|
|
14
|
+
*/
|
|
15
|
+
createBrowser(navig: Navigator, device: BrowserContextOptions | undefined, channel?: string | undefined): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* **Create a new page and activate it**
|
|
18
|
+
*/
|
|
19
|
+
createPage(): Promise<Page | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* **Return current active page**
|
|
22
|
+
*
|
|
23
|
+
* return 'undefined' if there is no active page
|
|
24
|
+
*/
|
|
25
|
+
getActivePage(): Page | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* **Return the handle of the current active page**
|
|
28
|
+
*
|
|
29
|
+
* The handle is a number converted to string
|
|
30
|
+
*/
|
|
31
|
+
getCurrentPageHandle(): string;
|
|
32
|
+
/**
|
|
33
|
+
* **Switch to another existing page and activate it**
|
|
34
|
+
*
|
|
35
|
+
* Return false if handle does not match any page, otherwise return true.
|
|
36
|
+
* @param handle String that is a unique page identifier
|
|
37
|
+
*/
|
|
38
|
+
switchToPage(handle: string): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* **Return a promise for a new page**
|
|
41
|
+
*
|
|
42
|
+
* To be used with ***switchToNewPage***
|
|
43
|
+
*/
|
|
44
|
+
pagePromise(): Promise<Page> | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* **Switch to a new page opened on another tab by a previous action**
|
|
47
|
+
* @param pagePromise the promise of new page
|
|
48
|
+
*/
|
|
49
|
+
switchToNewPage(pagePromise: Promise<Page>): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* **Wait current active page to be loaded**
|
|
52
|
+
*/
|
|
53
|
+
waitForLoadActivePage(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* **Close browser**
|
|
56
|
+
*/
|
|
57
|
+
close(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
declare const core: CoreBrowser;
|
|
60
|
+
export default core;
|
|
61
|
+
//# sourceMappingURL=Core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Core.d.ts","sourceRoot":"","sources":["../../src/core/Core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA0B,IAAI,EAAC,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AAE3D,KAAK,SAAS,GAAG,OAAO,QAAQ,GAAG,OAAO,OAAO,GAAG,OAAO,MAAM,CAAA;AAEjE,cAAM,WAAW;IACf,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,aAAa,CAAe;IAEpC;;;;;OAKG;IACU,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,qBAAqB,GAAG,SAAS,EAAE,OAAO,GAAC,MAAM,GAAC,SAAqB;IAK5H;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAUpD;;;;OAIG;IACI,aAAa,IAAI,IAAI,GAAG,SAAS;IAOxC;;;;OAIG;IACI,oBAAoB;IAI3B;;;;;OAKG;IACU,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAY3D;;;;OAIG;IACI,WAAW;IAIlB;;;OAGG;IACU,eAAe,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC;IASvD;;OAEG;IACU,qBAAqB;IAOlC;;OAEG;IACU,KAAK;CAQnB;AAED,QAAA,MAAM,IAAI,aAAoB,CAAA;AAC9B,eAAe,IAAI,CAAA"}
|
package/bin/core/Core.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { chromium, firefox, webkit } from "playwright";
|
|
2
|
+
class CoreBrowser {
|
|
3
|
+
browser;
|
|
4
|
+
ctx;
|
|
5
|
+
idxActivePage = '-1';
|
|
6
|
+
/**
|
|
7
|
+
* **Launch browser and retrieve appropriate context**
|
|
8
|
+
* @param navig chromium or firefox or webkit
|
|
9
|
+
* @param device kind of device (ex : iPhone11, Desktop Firefox, ...)
|
|
10
|
+
* @param channel required for some devices : chrome or firefox or msedge
|
|
11
|
+
*/
|
|
12
|
+
async createBrowser(navig, device, channel = undefined) {
|
|
13
|
+
this.browser = await navig.launch({ channel, headless: false });
|
|
14
|
+
this.ctx = await this.browser.newContext(device);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* **Create a new page and activate it**
|
|
18
|
+
*/
|
|
19
|
+
async createPage() {
|
|
20
|
+
if (this.ctx) {
|
|
21
|
+
const page = await this.ctx.newPage();
|
|
22
|
+
this.idxActivePage = (this.ctx.pages().length - 1).toString();
|
|
23
|
+
await page.bringToFront();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* **Return current active page**
|
|
31
|
+
*
|
|
32
|
+
* return 'undefined' if there is no active page
|
|
33
|
+
*/
|
|
34
|
+
getActivePage() {
|
|
35
|
+
const idx = Number(this.idxActivePage);
|
|
36
|
+
if (this.ctx && idx > -1) {
|
|
37
|
+
return this.ctx.pages()[idx];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* **Return the handle of the current active page**
|
|
42
|
+
*
|
|
43
|
+
* The handle is a number converted to string
|
|
44
|
+
*/
|
|
45
|
+
getCurrentPageHandle() {
|
|
46
|
+
return this.idxActivePage;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* **Switch to another existing page and activate it**
|
|
50
|
+
*
|
|
51
|
+
* Return false if handle does not match any page, otherwise return true.
|
|
52
|
+
* @param handle String that is a unique page identifier
|
|
53
|
+
*/
|
|
54
|
+
async switchToPage(handle) {
|
|
55
|
+
const idx = Number(handle);
|
|
56
|
+
if (this.ctx && idx > -1 && idx <= this.ctx.pages().length) {
|
|
57
|
+
const page = this.ctx.pages()[idx];
|
|
58
|
+
await page.bringToFront();
|
|
59
|
+
this.idxActivePage = handle;
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* **Return a promise for a new page**
|
|
68
|
+
*
|
|
69
|
+
* To be used with ***switchToNewPage***
|
|
70
|
+
*/
|
|
71
|
+
pagePromise() {
|
|
72
|
+
return this.ctx ? this.ctx.waitForEvent('page') : undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* **Switch to a new page opened on another tab by a previous action**
|
|
76
|
+
* @param pagePromise the promise of new page
|
|
77
|
+
*/
|
|
78
|
+
async switchToNewPage(pagePromise) {
|
|
79
|
+
const newPage = await pagePromise;
|
|
80
|
+
await newPage.waitForLoadState('load');
|
|
81
|
+
await newPage.bringToFront();
|
|
82
|
+
if (this.ctx) {
|
|
83
|
+
this.idxActivePage = (this.ctx.pages().length - 1).toString();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* **Wait current active page to be loaded**
|
|
88
|
+
*/
|
|
89
|
+
async waitForLoadActivePage() {
|
|
90
|
+
const page = this.getActivePage();
|
|
91
|
+
if (page) {
|
|
92
|
+
await page.waitForLoadState();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* **Close browser**
|
|
97
|
+
*/
|
|
98
|
+
async close() {
|
|
99
|
+
if (this.ctx) {
|
|
100
|
+
await this.ctx.close();
|
|
101
|
+
}
|
|
102
|
+
if (this.browser) {
|
|
103
|
+
await this.browser.close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const core = new CoreBrowser();
|
|
108
|
+
export default core;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { StepContext } from "@kogeet/scapin-core-agent";
|
|
2
|
+
import type { Locator } from "playwright";
|
|
3
|
+
export default function uiWrapper(stepCtx: StepContext, callback: (stepCtx: StepContext, elem: Locator) => Promise<boolean>): Promise<boolean>;
|
|
4
|
+
//# sourceMappingURL=LocatorLib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocatorLib.d.ts","sourceRoot":"","sources":["../../src/core/LocatorLib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAE1E,OAAO,KAAK,EAAe,OAAO,EAAC,MAAM,YAAY,CAAC;AAKtD,wBAA8B,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,oBAchI"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { report } from "@kogeet/scapin-core-agent";
|
|
2
|
+
import core from "./Core.js";
|
|
3
|
+
export default async function uiWrapper(stepCtx, callback) {
|
|
4
|
+
const wl = new LocatorLib(stepCtx.getAllConfigs());
|
|
5
|
+
const elem = await wl.findLocator();
|
|
6
|
+
if (elem) {
|
|
7
|
+
if (await elem.count() > 1) {
|
|
8
|
+
report.warning('> Found more than one éléments. Take the first one');
|
|
9
|
+
}
|
|
10
|
+
return await callback(stepCtx, elem.first());
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
report.warning('No elem found');
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class LocatorLib {
|
|
18
|
+
configList;
|
|
19
|
+
locator = null;
|
|
20
|
+
frameLocator = null;
|
|
21
|
+
constructor(configList) {
|
|
22
|
+
this.configList = configList;
|
|
23
|
+
}
|
|
24
|
+
async findLocator() {
|
|
25
|
+
this.locator = null;
|
|
26
|
+
if (this.configList && this.configList.length) {
|
|
27
|
+
for (let idx = 0; idx < this.configList.length; idx++) {
|
|
28
|
+
const { key, value } = this.configList[idx];
|
|
29
|
+
let selector = null;
|
|
30
|
+
let supported_key = true;
|
|
31
|
+
switch (key) {
|
|
32
|
+
case 'id':
|
|
33
|
+
selector = `#${value}`;
|
|
34
|
+
break;
|
|
35
|
+
case 'selector':
|
|
36
|
+
case 'iframe':
|
|
37
|
+
selector = `${value}`;
|
|
38
|
+
break;
|
|
39
|
+
case 'class':
|
|
40
|
+
selector = `.${value}`;
|
|
41
|
+
break;
|
|
42
|
+
case 'rank':
|
|
43
|
+
await this.nthLocator(value);
|
|
44
|
+
break;
|
|
45
|
+
case 'name':
|
|
46
|
+
selector = `[name="${value}"]`;
|
|
47
|
+
break;
|
|
48
|
+
case 'role':
|
|
49
|
+
selector = `[role="${value}"]`;
|
|
50
|
+
break;
|
|
51
|
+
case 'exactText':
|
|
52
|
+
this.getByText(value, true);
|
|
53
|
+
break;
|
|
54
|
+
case 'partialText':
|
|
55
|
+
this.getByText(value, false);
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
console.log(`> Mapping ${key} not supported or deprecated`);
|
|
59
|
+
supported_key = false;
|
|
60
|
+
}
|
|
61
|
+
if (supported_key) {
|
|
62
|
+
this.getLocator(idx, selector);
|
|
63
|
+
await this.logLocator(key, value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// erreur de paramètre
|
|
69
|
+
report.info('Mapping parameters not found');
|
|
70
|
+
}
|
|
71
|
+
return this.locator;
|
|
72
|
+
}
|
|
73
|
+
getLocator(idx, selector) {
|
|
74
|
+
const page = core.getActivePage();
|
|
75
|
+
if (page) {
|
|
76
|
+
if (selector) {
|
|
77
|
+
if (idx === 0) {
|
|
78
|
+
this.locator = page.locator(selector);
|
|
79
|
+
}
|
|
80
|
+
else if (this.locator) {
|
|
81
|
+
this.locator = this.locator.locator(selector);
|
|
82
|
+
}
|
|
83
|
+
else if (this.frameLocator) {
|
|
84
|
+
this.locator = this.frameLocator.locator(selector);
|
|
85
|
+
this.frameLocator = null;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// selector != null && idx > 0 && this.locator = null && this.frameLocator = null
|
|
89
|
+
report.info('No such element error');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
report.info('No browser available');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async logLocator(key, value) {
|
|
98
|
+
if (this.locator) {
|
|
99
|
+
try {
|
|
100
|
+
// Needed for Locator inside an iframe to be found
|
|
101
|
+
await this.locator.first().waitFor();
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
console.log(`> [${key}: ${value}] wait for locator failed`);
|
|
105
|
+
await core.close();
|
|
106
|
+
throw new Error('LOCATOR_TIMEOUT');
|
|
107
|
+
}
|
|
108
|
+
const count = await this.locator.count();
|
|
109
|
+
console.log(`> [${key}: ${value}] found ${count} éléments`);
|
|
110
|
+
if (key === 'iframe') {
|
|
111
|
+
this.frameLocator = this.locator.first().frameLocator(':scope');
|
|
112
|
+
this.locator = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.log(`> [${key}: ${value}] found 0 éléments`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async nthLocator(value) {
|
|
120
|
+
if (this.locator) {
|
|
121
|
+
const count = await this.locator.count();
|
|
122
|
+
let nth = +value - 1;
|
|
123
|
+
if (nth < 0)
|
|
124
|
+
nth = 0;
|
|
125
|
+
if (nth >= count)
|
|
126
|
+
nth = count - 1;
|
|
127
|
+
this.locator = this.locator.nth(nth);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
getByText(value, exact) {
|
|
131
|
+
if (this.locator) {
|
|
132
|
+
this.locator = this.locator.getByText(value, { exact });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
package/bin/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// La ligne ci-dessus est requise pour que la commande sagent-playwright fonctionne
|
|
3
|
+
// après installation du package en global
|
|
4
|
+
import { sagent } from "@kogeet/scapin-core-agent";
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import BrowserLib from "./libs/BrowserLib.js";
|
|
7
|
+
import StdLib from "./libs/StdLib.js";
|
|
8
|
+
import DatasetEntryPoints from "@kogeet/sagent-plugin-dataset";
|
|
9
|
+
const loadJSON = (path) => JSON.parse(fs.readFileSync(new URL(path, import.meta.url)).toString());
|
|
10
|
+
const pjson = loadJSON('../package.json');
|
|
11
|
+
// Librairies prises en charge
|
|
12
|
+
sagent.use('BrowserLib', BrowserLib.entryPoints);
|
|
13
|
+
sagent.use('StdLib', StdLib.entryPoints);
|
|
14
|
+
sagent.use('DatasetLib', DatasetEntryPoints);
|
|
15
|
+
console.log('Starting Scapin Playwright Agent version', pjson.version);
|
|
16
|
+
sagent.listen();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StepContext } from "@kogeet/scapin-core-agent";
|
|
2
|
+
export default class BrowserLib {
|
|
3
|
+
static entryPoints: Map<string, typeof BrowserLib.BrowserRunToURL>;
|
|
4
|
+
static BrowserRunToURL(stepCtx: StepContext): Promise<boolean>;
|
|
5
|
+
static BrowserQuit(): Promise<boolean>;
|
|
6
|
+
static BrowserGotoURL(stepCtx: StepContext): Promise<boolean>;
|
|
7
|
+
static BrowserBack(): Promise<boolean>;
|
|
8
|
+
static BrowserForward(): Promise<boolean>;
|
|
9
|
+
static BrowserGetTitle(stepCtx: StepContext): Promise<boolean>;
|
|
10
|
+
static BrowserHasTitle(stepCtx: StepContext): Promise<boolean>;
|
|
11
|
+
static BrowserRefresh(): Promise<boolean>;
|
|
12
|
+
static BrowserTabToUrl(stepCtx: StepContext): Promise<boolean>;
|
|
13
|
+
static BrowserWindowToUrl(stepCtx: StepContext): Promise<boolean>;
|
|
14
|
+
static BrowserSwitch(stepCtx: StepContext): Promise<boolean>;
|
|
15
|
+
static BrowserGetCurrentURL(stepCtx: StepContext): Promise<boolean>;
|
|
16
|
+
private static goToUrl;
|
|
17
|
+
private static browserToUrl;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=BrowserLib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrowserLib.d.ts","sourceRoot":"","sources":["../../src/libs/BrowserLib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAIvE,MAAM,CAAC,OAAO,OAAO,UAAU;IAE7B,OAAc,WAAW,iDAavB;WAEkB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAsCvD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;WAU/B,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAUtD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;WAgB/B,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;WAgBlC,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAiBvD,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAiBvD,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;WAgBlC,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAQvD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WAM1D,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;WASrD,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;mBAiB3D,OAAO;mBAWP,YAAY;CAYlC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { context, report, StepContext } from "@kogeet/scapin-core-agent";
|
|
2
|
+
import { chromium, devices, firefox } from "playwright";
|
|
3
|
+
import core from "../core/Core.js";
|
|
4
|
+
export default class BrowserLib {
|
|
5
|
+
static entryPoints = new Map([
|
|
6
|
+
['browserRunToURL', BrowserLib.BrowserRunToURL],
|
|
7
|
+
['browserQuit', BrowserLib.BrowserQuit],
|
|
8
|
+
['browserGotoURL', BrowserLib.BrowserGotoURL],
|
|
9
|
+
['browserBack', BrowserLib.BrowserBack],
|
|
10
|
+
['browserForward', BrowserLib.BrowserForward],
|
|
11
|
+
['browserGetTitle', BrowserLib.BrowserGetTitle],
|
|
12
|
+
['browserHasTitle', BrowserLib.BrowserHasTitle],
|
|
13
|
+
['browserRefresh', BrowserLib.BrowserRefresh],
|
|
14
|
+
['browserWin2Url', BrowserLib.BrowserWindowToUrl],
|
|
15
|
+
['browserTab2Url', BrowserLib.BrowserTabToUrl],
|
|
16
|
+
['browserSwitch', BrowserLib.BrowserSwitch],
|
|
17
|
+
['browserGetCurrentURL', BrowserLib.BrowserGetCurrentURL]
|
|
18
|
+
]);
|
|
19
|
+
static async BrowserRunToURL(stepCtx) {
|
|
20
|
+
// Récupération des paramètres
|
|
21
|
+
const browserName = stepCtx.getStringParam('0');
|
|
22
|
+
const url = (stepCtx.getStringParam('1')).toLowerCase();
|
|
23
|
+
// Exécution
|
|
24
|
+
try {
|
|
25
|
+
switch (browserName) {
|
|
26
|
+
case 'chrome':
|
|
27
|
+
await core.createBrowser(chromium, { ...devices['Desktop Chrome'] }, 'chrome');
|
|
28
|
+
break;
|
|
29
|
+
case 'firefox':
|
|
30
|
+
await core.createBrowser(firefox, { ...devices['Desktop Firefox'] }, 'firefox');
|
|
31
|
+
break;
|
|
32
|
+
case 'msedge':
|
|
33
|
+
await core.createBrowser(chromium, { ...devices['Desktop Edge'] }, 'msedge');
|
|
34
|
+
break;
|
|
35
|
+
case 'pixel5':
|
|
36
|
+
await core.createBrowser(chromium, { ...devices['Pixel 5'] });
|
|
37
|
+
break;
|
|
38
|
+
case 'pixel5L':
|
|
39
|
+
await core.createBrowser(chromium, { ...devices['Pixel 5 landscape'] });
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
report.error(`LaunchToUrl value '${browserName}' is invalid for Browser parameter`);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
await core.createPage();
|
|
46
|
+
context.setVariable(stepCtx.getStringParam('2'), core.getCurrentPageHandle());
|
|
47
|
+
return await BrowserLib.goToUrl(url, 'LaunchToUrl');
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
report.error(`LaunchToUrl error for '${browserName}' : ${e.message}`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static async BrowserQuit() {
|
|
55
|
+
try {
|
|
56
|
+
await core.close();
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
report.error(`Quit browser error : ${e.message}`);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
static async BrowserGotoURL(stepCtx) {
|
|
65
|
+
const url = stepCtx.getStringParam('0');
|
|
66
|
+
try {
|
|
67
|
+
return await BrowserLib.goToUrl(url, 'GoToUrl');
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
report.error(`GoToUrl error : ${e.message}`);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
static async BrowserBack() {
|
|
75
|
+
try {
|
|
76
|
+
const page = core.getActivePage();
|
|
77
|
+
if (page) {
|
|
78
|
+
await page.goBack();
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
report.error(`Back unexpected error : There is no active page`);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
report.error(`Back error : ${e.message}`);
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
static async BrowserForward() {
|
|
92
|
+
try {
|
|
93
|
+
const page = core.getActivePage();
|
|
94
|
+
if (page) {
|
|
95
|
+
await page.goForward();
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
report.error(`Forward unexpected error : There is no active page`);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
report.error(`Forward error : ${e.message}`);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
static async BrowserGetTitle(stepCtx) {
|
|
109
|
+
try {
|
|
110
|
+
const page = core.getActivePage();
|
|
111
|
+
if (page) {
|
|
112
|
+
const title = await page.title();
|
|
113
|
+
context.setVariable(stepCtx.getStringParam('0'), title);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
report.error(`GetTitle unexpected error : There is no active page`);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
report.error(`GetTitle error : ${e.message}`);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
static async BrowserHasTitle(stepCtx) {
|
|
127
|
+
try {
|
|
128
|
+
const page = core.getActivePage();
|
|
129
|
+
if (page) {
|
|
130
|
+
const title = await page.title();
|
|
131
|
+
return stepCtx.getStringParam('0') === title;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
report.error(`HasTitle unexpected error : There is no active page`);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
report.error(`HasTitle error : ${e.message}`);
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
static async BrowserRefresh() {
|
|
144
|
+
try {
|
|
145
|
+
const page = core.getActivePage();
|
|
146
|
+
if (page) {
|
|
147
|
+
await page.reload();
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
report.error(`Refresh unexpected error : There is no active page`);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
report.error(`Refresh error : ${e.message}`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
static async BrowserTabToUrl(stepCtx) {
|
|
161
|
+
const url = stepCtx.getStringParam('0');
|
|
162
|
+
const varName = stepCtx.getStringParam('1');
|
|
163
|
+
return await BrowserLib.browserToUrl(url, varName, 'OpenTabToUrl');
|
|
164
|
+
}
|
|
165
|
+
// 'BrowserWindowToUrl' est maintenu pour des raisons de compatibilité avec Selenium
|
|
166
|
+
// mais fait la même chose que 'BrowserTabToUrl'
|
|
167
|
+
static async BrowserWindowToUrl(stepCtx) {
|
|
168
|
+
const url = stepCtx.getStringParam('0');
|
|
169
|
+
const varName = stepCtx.getStringParam('1');
|
|
170
|
+
return await BrowserLib.browserToUrl(url, varName, 'OpenWindowToUrl');
|
|
171
|
+
}
|
|
172
|
+
static async BrowserSwitch(stepCtx) {
|
|
173
|
+
try {
|
|
174
|
+
return core.switchToPage(stepCtx.getStringParam('0'));
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
report.error(`SwitchTo error : ${e.message}`);
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
static async BrowserGetCurrentURL(stepCtx) {
|
|
182
|
+
try {
|
|
183
|
+
const page = core.getActivePage();
|
|
184
|
+
if (page) {
|
|
185
|
+
context.setVariable(stepCtx.getStringParam('0'), page.url());
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
report.error(`GetTabUrl unexpected error : There is no active page`);
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
report.error(`GetTabUrl error : ${e.message}`);
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
static async goToUrl(url, fromMsg = '') {
|
|
199
|
+
const page = core.getActivePage();
|
|
200
|
+
if (page) {
|
|
201
|
+
await page.goto(url);
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
report.error(`${fromMsg} unexpected error : There is no active page`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
static async browserToUrl(url, varName, fromMsg) {
|
|
210
|
+
try {
|
|
211
|
+
await core.createPage();
|
|
212
|
+
context.setVariable(varName, core.getCurrentPageHandle());
|
|
213
|
+
return await BrowserLib.goToUrl(url, fromMsg);
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
report.error(`${fromMsg} error : ${e.message}`);
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { StepContext } from "@kogeet/scapin-core-agent";
|
|
2
|
+
export default class StdLib {
|
|
3
|
+
static entryPoints: Map<string, typeof StdLib.elemClick>;
|
|
4
|
+
/**
|
|
5
|
+
* **Implémentation de l'instruction d'action Click**
|
|
6
|
+
* @param stepCtx Paramètre du step
|
|
7
|
+
*/
|
|
8
|
+
static elemClick(stepCtx: StepContext): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* **Implémentation de l'instruction d'action InputText**
|
|
11
|
+
* @param stepCtx Paramètre du step
|
|
12
|
+
*/
|
|
13
|
+
static elemSetText(stepCtx: StepContext): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* **Implémentation de l'instruction d'action GetText**
|
|
16
|
+
*
|
|
17
|
+
* Retrieve the text of an element
|
|
18
|
+
* @param stepCtx Paramètre du step
|
|
19
|
+
*/
|
|
20
|
+
static elemGetText(stepCtx: StepContext): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* **Implémentation de l'instruction de contrôle HasText**
|
|
23
|
+
*
|
|
24
|
+
* Renvoie *true* si le texte passé en paramètre est celui de l'élément
|
|
25
|
+
* @param stepCtx Paramètre du step
|
|
26
|
+
*/
|
|
27
|
+
static elemHasText(stepCtx: StepContext): Promise<boolean>;
|
|
28
|
+
/**
|
|
29
|
+
* **Implémentation de l'instruction de contrôle IsVisible**
|
|
30
|
+
* @param stepCtx Paramètre du step
|
|
31
|
+
*/
|
|
32
|
+
static elemIsVisible(stepCtx: StepContext): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* **Implémentation de l'instruction de contrôle IsEnabled**
|
|
35
|
+
* @param stepCtx Paramètre du step
|
|
36
|
+
*/
|
|
37
|
+
static elemIsEnabled(stepCtx: StepContext): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* **Implémentation de l'instruction de contrôle HasState**
|
|
40
|
+
*
|
|
41
|
+
* Contrôle l'état coché ou non d'une checkbox ou d'un radio-bouton
|
|
42
|
+
* @param stepCtx Paramètre du step
|
|
43
|
+
*/
|
|
44
|
+
static elemHasState(stepCtx: StepContext): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* **Implémentation de l'instruction d'action GetState**
|
|
47
|
+
*
|
|
48
|
+
* Récupère l'état coché ou décoché d'une checkbox ou d'un radio-bouton
|
|
49
|
+
* @param stepCtx Paramètre du step
|
|
50
|
+
*/
|
|
51
|
+
static elemGetState(stepCtx: StepContext): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* **Implémentation de l'instruction d'action setState**
|
|
54
|
+
*
|
|
55
|
+
* Coche ou décoche une checkbox ou un radio-bouton
|
|
56
|
+
* @param stepCtx Paramètre du step
|
|
57
|
+
*/
|
|
58
|
+
static elemSetState(stepCtx: StepContext): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* **Implémentation de l'instruction d'action ClickAndOpen**
|
|
61
|
+
* @param stepCtx Paramètre du step
|
|
62
|
+
*/
|
|
63
|
+
static elemClickToNew(stepCtx: StepContext): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* **Implémentation de l'instruction d'action setTimer**
|
|
66
|
+
* @param stepCtx Paramètre du step
|
|
67
|
+
*/
|
|
68
|
+
static wait(stepCtx: StepContext): Promise<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* **Implémentation de l'instruction d'action Calculator**
|
|
71
|
+
* @param stepCtx Paramètre du step
|
|
72
|
+
*/
|
|
73
|
+
static calculator(stepCtx: StepContext): Promise<boolean>;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=StdLib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdLib.d.ts","sourceRoot":"","sources":["../../src/libs/StdLib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAM3D,MAAM,CAAC,OAAO,OAAO,MAAM;IAEzB,OAAc,WAAW,uCAavB;IAEF;;;OAGG;WACiB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAarE;;;OAGG;WACiB,WAAW,CAAC,OAAO,EAAE,WAAW;IAiBpD;;;;;OAKG;WACiB,WAAW,CAAC,OAAO,EAAE,WAAW;IAapD;;;;;OAKG;WACiB,WAAW,CAAC,OAAO,EAAE,WAAW;IAqBpD;;;OAGG;WACiB,aAAa,CAAC,OAAO,EAAE,WAAW;IAYtD;;;OAGG;WACiB,aAAa,CAAC,OAAO,EAAE,WAAW;IAYtD;;;;;OAKG;WACiB,YAAY,CAAC,OAAO,EAAE,WAAW;IAarD;;;;;OAKG;WACiB,YAAY,CAAC,OAAO,EAAE,WAAW;IAYrD;;;;;OAKG;WACiB,YAAY,CAAC,OAAO,EAAE,WAAW;IAgBrD;;;OAGG;WACiB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1E;;;OAGG;WACiB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhE;;;OAGG;WACiB,UAAU,CAAC,OAAO,EAAE,WAAW;CAkCpD"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import uiWrapper from "../core/LocatorLib.js";
|
|
2
|
+
import { context, report } from "@kogeet/scapin-core-agent";
|
|
3
|
+
import core from "../core/Core.js";
|
|
4
|
+
export default class StdLib {
|
|
5
|
+
static entryPoints = new Map([
|
|
6
|
+
['elemClick', StdLib.elemClick],
|
|
7
|
+
['elemSetText', StdLib.elemSetText],
|
|
8
|
+
['elemGetText', StdLib.elemGetText],
|
|
9
|
+
['elemHasText', StdLib.elemHasText],
|
|
10
|
+
['elemIsVisible', StdLib.elemIsVisible],
|
|
11
|
+
['elemIsEnabled', StdLib.elemIsEnabled],
|
|
12
|
+
['elemHasState', StdLib.elemHasState],
|
|
13
|
+
['elemGetState', StdLib.elemGetState],
|
|
14
|
+
['elemSetState', StdLib.elemSetState],
|
|
15
|
+
['elemClickToNew', StdLib.elemClickToNew],
|
|
16
|
+
['wait', StdLib.wait],
|
|
17
|
+
['calculator', StdLib.calculator]
|
|
18
|
+
]);
|
|
19
|
+
/**
|
|
20
|
+
* **Implémentation de l'instruction d'action Click**
|
|
21
|
+
* @param stepCtx Paramètre du step
|
|
22
|
+
*/
|
|
23
|
+
static async elemClick(stepCtx) {
|
|
24
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
25
|
+
try {
|
|
26
|
+
await elem.click();
|
|
27
|
+
await core.waitForLoadActivePage();
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
report.warning(`Paywright error on 'Click' instruction : ${e.message}`);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* **Implémentation de l'instruction d'action InputText**
|
|
38
|
+
* @param stepCtx Paramètre du step
|
|
39
|
+
*/
|
|
40
|
+
static async elemSetText(stepCtx) {
|
|
41
|
+
const text = stepCtx.getStringParam('0', '');
|
|
42
|
+
// const clickBefore = stepCtx.getParam('1', true) Obsolète avec Playwright
|
|
43
|
+
// const eraseBefore = stepCtx.getParam('2', false) Obsolète avec Playwright
|
|
44
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
45
|
+
try {
|
|
46
|
+
await elem.fill(text);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
report.warning(`Paywright error on 'InputText' instruction : ${e.message}`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* **Implémentation de l'instruction d'action GetText**
|
|
57
|
+
*
|
|
58
|
+
* Retrieve the text of an element
|
|
59
|
+
* @param stepCtx Paramètre du step
|
|
60
|
+
*/
|
|
61
|
+
static async elemGetText(stepCtx) {
|
|
62
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
63
|
+
try {
|
|
64
|
+
const text = await elem.innerText();
|
|
65
|
+
context.setVariable(stepCtx.getStringParam('0'), text);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
report.warning(`Paywright error on 'GetText' instruction : ${e.message}`);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* **Implémentation de l'instruction de contrôle HasText**
|
|
76
|
+
*
|
|
77
|
+
* Renvoie *true* si le texte passé en paramètre est celui de l'élément
|
|
78
|
+
* @param stepCtx Paramètre du step
|
|
79
|
+
*/
|
|
80
|
+
static async elemHasText(stepCtx) {
|
|
81
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
82
|
+
try {
|
|
83
|
+
const text = await elem.innerText();
|
|
84
|
+
let pattern = stepCtx.getStringParam('0');
|
|
85
|
+
if (stepCtx.getParam('1', false) === true) {
|
|
86
|
+
pattern = `^${pattern}$`;
|
|
87
|
+
}
|
|
88
|
+
const regex = new RegExp(pattern);
|
|
89
|
+
const found = text.match(regex);
|
|
90
|
+
return !!found;
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
report.warning(`Paywright error on 'HasText' instruction : ${e.message}`);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* **Implémentation de l'instruction de contrôle IsVisible**
|
|
100
|
+
* @param stepCtx Paramètre du step
|
|
101
|
+
*/
|
|
102
|
+
static async elemIsVisible(stepCtx) {
|
|
103
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
104
|
+
try {
|
|
105
|
+
const elemVisible = await elem.isVisible();
|
|
106
|
+
return elemVisible === stepCtx.getParam('0', true);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
report.warning(`Paywright error on 'IsVisible' instruction : ${e.message}`);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* **Implémentation de l'instruction de contrôle IsEnabled**
|
|
116
|
+
* @param stepCtx Paramètre du step
|
|
117
|
+
*/
|
|
118
|
+
static async elemIsEnabled(stepCtx) {
|
|
119
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
120
|
+
try {
|
|
121
|
+
const elemEnabled = await elem.isEnabled();
|
|
122
|
+
return elemEnabled === stepCtx.getParam('0', true);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
report.warning(`Paywright error on 'IsEnabled' instruction : ${e.message}`);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* **Implémentation de l'instruction de contrôle HasState**
|
|
132
|
+
*
|
|
133
|
+
* Contrôle l'état coché ou non d'une checkbox ou d'un radio-bouton
|
|
134
|
+
* @param stepCtx Paramètre du step
|
|
135
|
+
*/
|
|
136
|
+
static async elemHasState(stepCtx) {
|
|
137
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
138
|
+
try {
|
|
139
|
+
const state = await elem.isChecked();
|
|
140
|
+
return state === stepCtx.getParam('0', true);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
report.warning(`Paywright error on 'HasState' instruction : ${e.message}`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* **Implémentation de l'instruction d'action GetState**
|
|
150
|
+
*
|
|
151
|
+
* Récupère l'état coché ou décoché d'une checkbox ou d'un radio-bouton
|
|
152
|
+
* @param stepCtx Paramètre du step
|
|
153
|
+
*/
|
|
154
|
+
static async elemGetState(stepCtx) {
|
|
155
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
156
|
+
try {
|
|
157
|
+
context.setVariable(stepCtx.getStringParam('0'), await elem.isChecked());
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
report.warning(`Paywright error on 'GetState' instruction : ${e.message}`);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* **Implémentation de l'instruction d'action setState**
|
|
168
|
+
*
|
|
169
|
+
* Coche ou décoche une checkbox ou un radio-bouton
|
|
170
|
+
* @param stepCtx Paramètre du step
|
|
171
|
+
*/
|
|
172
|
+
static async elemSetState(stepCtx) {
|
|
173
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
174
|
+
try {
|
|
175
|
+
if (stepCtx.getParam('0', true)) {
|
|
176
|
+
await elem.check();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
await elem.uncheck();
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
report.warning(`Paywright error on 'SetState' instruction : ${e.message}`);
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* **Implémentation de l'instruction d'action ClickAndOpen**
|
|
191
|
+
* @param stepCtx Paramètre du step
|
|
192
|
+
*/
|
|
193
|
+
static async elemClickToNew(stepCtx) {
|
|
194
|
+
return await uiWrapper(stepCtx, async (stepCtx, elem) => {
|
|
195
|
+
try {
|
|
196
|
+
const pagePromise = core.pagePromise();
|
|
197
|
+
if (pagePromise) {
|
|
198
|
+
await elem.click();
|
|
199
|
+
await core.switchToNewPage(pagePromise);
|
|
200
|
+
context.setVariable(stepCtx.getStringParam('0'), core.getCurrentPageHandle());
|
|
201
|
+
}
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
report.warning(`Paywright error on 'ClickAndOpen' instruction : ${e.message}`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* **Implémentation de l'instruction d'action setTimer**
|
|
212
|
+
* @param stepCtx Paramètre du step
|
|
213
|
+
*/
|
|
214
|
+
static async wait(stepCtx) {
|
|
215
|
+
const t = stepCtx.getParam('0', stepCtx.getConfig('0', 0));
|
|
216
|
+
await delay(t);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* **Implémentation de l'instruction d'action Calculator**
|
|
221
|
+
* @param stepCtx Paramètre du step
|
|
222
|
+
*/
|
|
223
|
+
static async calculator(stepCtx) {
|
|
224
|
+
context.setVariable(stepCtx.getStringParam('1'), stepCtx.getParam('0'));
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function delay(t) {
|
|
229
|
+
return new Promise((done) => {
|
|
230
|
+
setTimeout(() => {
|
|
231
|
+
done();
|
|
232
|
+
}, t);
|
|
233
|
+
});
|
|
234
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kogeet/sagent-playwright",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scapin Agent for Playwright",
|
|
5
|
+
"main": "bin/index.js",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": "^18.17.1"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc --sourceMap false --declaration true",
|
|
14
|
+
"termprod": "npm run build && node bin/index.js",
|
|
15
|
+
"np": "np --no-tests --message=sagent-playwright-%s"
|
|
16
|
+
},
|
|
17
|
+
"author": "Loïc Griveau",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@kogeet/sagent-plugin-dataset": "^0.1.1",
|
|
21
|
+
"@kogeet/scapin-core-agent": "^0.1.5",
|
|
22
|
+
"@playwright/browser-chromium": "^1.39.0",
|
|
23
|
+
"@playwright/browser-firefox": "^1.39.0",
|
|
24
|
+
"@playwright/browser-webkit": "^1.39.0",
|
|
25
|
+
"playwright": "^1.39.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^20.8.10",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
30
|
+
"@typescript-eslint/parser": "^6.8.0",
|
|
31
|
+
"eslint": "^8.51.0",
|
|
32
|
+
"typescript": "^5.2.2"
|
|
33
|
+
},
|
|
34
|
+
"type": "module",
|
|
35
|
+
"bin": {
|
|
36
|
+
"sagent-playwright": "bin/index.js"
|
|
37
|
+
}
|
|
38
|
+
}
|