@nouhouari/conductor-e2e 0.0.0-stage → 0.1.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/CHANGELOG.md +228 -0
- package/LICENSE +21 -0
- package/README.md +138 -2
- package/config/environments/default.ts +41 -0
- package/config/environments/dev.ts +16 -0
- package/config/environments/staging.ts +15 -0
- package/config/index.ts +70 -0
- package/config/types.ts +94 -0
- package/dist/config/environments/default.d.ts +3 -0
- package/dist/config/environments/default.d.ts.map +1 -0
- package/dist/config/environments/default.js +40 -0
- package/dist/config/environments/default.js.map +1 -0
- package/dist/config/environments/dev.d.ts +3 -0
- package/dist/config/environments/dev.d.ts.map +1 -0
- package/dist/config/environments/dev.js +18 -0
- package/dist/config/environments/dev.js.map +1 -0
- package/dist/config/environments/staging.d.ts +3 -0
- package/dist/config/environments/staging.d.ts.map +1 -0
- package/dist/config/environments/staging.js +17 -0
- package/dist/config/environments/staging.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +81 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +93 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +3 -0
- package/dist/config/types.js.map +1 -0
- package/dist/src/drivers/ApiDriver.d.ts +16 -0
- package/dist/src/drivers/ApiDriver.d.ts.map +1 -0
- package/dist/src/drivers/ApiDriver.js +48 -0
- package/dist/src/drivers/ApiDriver.js.map +1 -0
- package/dist/src/drivers/DatabaseDriver.d.ts +12 -0
- package/dist/src/drivers/DatabaseDriver.d.ts.map +1 -0
- package/dist/src/drivers/DatabaseDriver.js +15 -0
- package/dist/src/drivers/DatabaseDriver.js.map +1 -0
- package/dist/src/drivers/FlutterDesktopDriver.d.ts +139 -0
- package/dist/src/drivers/FlutterDesktopDriver.d.ts.map +1 -0
- package/dist/src/drivers/FlutterDesktopDriver.js +445 -0
- package/dist/src/drivers/FlutterDesktopDriver.js.map +1 -0
- package/dist/src/drivers/MaestroDriver.d.ts +19 -0
- package/dist/src/drivers/MaestroDriver.d.ts.map +1 -0
- package/dist/src/drivers/MaestroDriver.js +144 -0
- package/dist/src/drivers/MaestroDriver.js.map +1 -0
- package/dist/src/drivers/WebDriver.d.ts +21 -0
- package/dist/src/drivers/WebDriver.d.ts.map +1 -0
- package/dist/src/drivers/WebDriver.js +57 -0
- package/dist/src/drivers/WebDriver.js.map +1 -0
- package/dist/src/hooks/browser.hooks.d.ts +2 -0
- package/dist/src/hooks/browser.hooks.d.ts.map +1 -0
- package/dist/src/hooks/browser.hooks.js +15 -0
- package/dist/src/hooks/browser.hooks.js.map +1 -0
- package/dist/src/hooks/database.hooks.d.ts +2 -0
- package/dist/src/hooks/database.hooks.d.ts.map +1 -0
- package/dist/src/hooks/database.hooks.js +11 -0
- package/dist/src/hooks/database.hooks.js.map +1 -0
- package/dist/src/hooks/desktop.hooks.d.ts +2 -0
- package/dist/src/hooks/desktop.hooks.d.ts.map +1 -0
- package/dist/src/hooks/desktop.hooks.js +15 -0
- package/dist/src/hooks/desktop.hooks.js.map +1 -0
- package/dist/src/hooks/flutterDesktop.hooks.d.ts +2 -0
- package/dist/src/hooks/flutterDesktop.hooks.d.ts.map +1 -0
- package/dist/src/hooks/flutterDesktop.hooks.js +26 -0
- package/dist/src/hooks/flutterDesktop.hooks.js.map +1 -0
- package/dist/src/hooks/index.d.ts +6 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/index.js +25 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/hooks/maestro.hooks.d.ts +2 -0
- package/dist/src/hooks/maestro.hooks.d.ts.map +1 -0
- package/dist/src/hooks/maestro.hooks.js +8 -0
- package/dist/src/hooks/maestro.hooks.js.map +1 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +30 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/pages/BasePage.d.ts +11 -0
- package/dist/src/pages/BasePage.d.ts.map +1 -0
- package/dist/src/pages/BasePage.js +22 -0
- package/dist/src/pages/BasePage.js.map +1 -0
- package/dist/src/scenarios/RemoteScenarioFetcher.d.ts +51 -0
- package/dist/src/scenarios/RemoteScenarioFetcher.d.ts.map +1 -0
- package/dist/src/scenarios/RemoteScenarioFetcher.js +162 -0
- package/dist/src/scenarios/RemoteScenarioFetcher.js.map +1 -0
- package/dist/src/scenarios/cli.d.ts +3 -0
- package/dist/src/scenarios/cli.d.ts.map +1 -0
- package/dist/src/scenarios/cli.js +26 -0
- package/dist/src/scenarios/cli.js.map +1 -0
- package/dist/src/support/logger.d.ts +3 -0
- package/dist/src/support/logger.d.ts.map +1 -0
- package/dist/src/support/logger.js +16 -0
- package/dist/src/support/logger.js.map +1 -0
- package/dist/src/support/retry.d.ts +7 -0
- package/dist/src/support/retry.d.ts.map +1 -0
- package/dist/src/support/retry.js +21 -0
- package/dist/src/support/retry.js.map +1 -0
- package/dist/src/world/ConductorWorld.d.ts +39 -0
- package/dist/src/world/ConductorWorld.d.ts.map +1 -0
- package/dist/src/world/ConductorWorld.js +112 -0
- package/dist/src/world/ConductorWorld.js.map +1 -0
- package/package.json +81 -4
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultConfig = void 0;
|
|
4
|
+
exports.defaultConfig = {
|
|
5
|
+
name: 'default',
|
|
6
|
+
web: {
|
|
7
|
+
baseUrl: 'http://localhost:3000',
|
|
8
|
+
headless: true,
|
|
9
|
+
browserName: 'chromium'
|
|
10
|
+
},
|
|
11
|
+
api: {
|
|
12
|
+
baseUrl: 'http://localhost:3000',
|
|
13
|
+
defaultCredentials: { username: 'test@example.com', password: 'password' },
|
|
14
|
+
timeoutMs: 30000
|
|
15
|
+
},
|
|
16
|
+
mobile: {
|
|
17
|
+
flowsDir: 'flows/mobile',
|
|
18
|
+
timeoutMs: 120000
|
|
19
|
+
},
|
|
20
|
+
database: {
|
|
21
|
+
enabled: false
|
|
22
|
+
},
|
|
23
|
+
desktop: {
|
|
24
|
+
agentJar: require('path').resolve(__dirname, '../../apps/desktop/agent/fxagent.jar'),
|
|
25
|
+
defaultTimeoutMs: 10000,
|
|
26
|
+
screenshotDir: 'reports/screenshots'
|
|
27
|
+
},
|
|
28
|
+
flutterDesktop: {
|
|
29
|
+
appPath: require('path').resolve(__dirname, '../../apps/mobile/build/macos/Build/Products/Profile/todoapp.app/Contents/MacOS/todoapp'),
|
|
30
|
+
defaultTimeoutMs: 10000,
|
|
31
|
+
launchTimeoutMs: 30000,
|
|
32
|
+
screenshotDir: 'reports/screenshots'
|
|
33
|
+
},
|
|
34
|
+
remoteScenarios: {
|
|
35
|
+
baseUrl: 'http://localhost:8788/api',
|
|
36
|
+
outputDir: '.remote-features',
|
|
37
|
+
filters: {}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../../config/environments/default.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAAsB;IAC9C,IAAI,EAAE,SAAS;IACf,GAAG,EAAE;QACH,OAAO,EAAE,uBAAuB;QAChC,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,UAAU;KACxB;IACD,GAAG,EAAE;QACH,OAAO,EAAE,uBAAuB;QAChC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,UAAU,EAAE;QAC1E,SAAS,EAAE,KAAK;KACjB;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,cAAc;QACxB,SAAS,EAAE,MAAM;KAClB;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,KAAK;KACf;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,sCAAsC,CAAC;QACpF,gBAAgB,EAAE,KAAK;QACvB,aAAa,EAAE,qBAAqB;KACrC;IACD,cAAc,EAAE;QACd,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAC9B,SAAS,EACT,yFAAyF,CAC1F;QACD,gBAAgB,EAAE,KAAK;QACvB,eAAe,EAAE,KAAK;QACtB,aAAa,EAAE,qBAAqB;KACrC;IACD,eAAe,EAAE;QACf,OAAO,EAAE,2BAA2B;QACpC,SAAS,EAAE,kBAAkB;QAC7B,OAAO,EAAE,EAAE;KACZ;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../config/environments/dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,SAAS,EAAE,OAAO,CAAC,iBAAiB,CAahD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.devConfig = void 0;
|
|
4
|
+
exports.devConfig = {
|
|
5
|
+
name: 'dev',
|
|
6
|
+
web: {
|
|
7
|
+
baseUrl: 'http://localhost:3000',
|
|
8
|
+
headless: false,
|
|
9
|
+
browserName: 'chromium',
|
|
10
|
+
slowMo: 100
|
|
11
|
+
},
|
|
12
|
+
api: {
|
|
13
|
+
baseUrl: 'http://localhost:3000/api',
|
|
14
|
+
defaultCredentials: { username: 'dev@example.com', password: 'devpassword' },
|
|
15
|
+
timeoutMs: 60000
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../config/environments/dev.ts"],"names":[],"mappings":";;;AAEa,QAAA,SAAS,GAA+B;IACnD,IAAI,EAAE,KAAK;IACX,GAAG,EAAE;QACH,OAAO,EAAE,uBAAuB;QAChC,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,UAAU;QACvB,MAAM,EAAE,GAAG;KACZ;IACD,GAAG,EAAE;QACH,OAAO,EAAE,2BAA2B;QACpC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE;QAC5E,SAAS,EAAE,KAAK;KACjB;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../../config/environments/staging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,eAAO,MAAM,aAAa,EAAE,OAAO,CAAC,iBAAiB,CAYpD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stagingConfig = void 0;
|
|
4
|
+
exports.stagingConfig = {
|
|
5
|
+
name: 'staging',
|
|
6
|
+
web: {
|
|
7
|
+
baseUrl: 'https://staging.example.com',
|
|
8
|
+
headless: true,
|
|
9
|
+
browserName: 'chromium'
|
|
10
|
+
},
|
|
11
|
+
api: {
|
|
12
|
+
baseUrl: 'https://staging.example.com/api',
|
|
13
|
+
defaultCredentials: { username: 'staging@example.com', password: 'stagingpassword' },
|
|
14
|
+
timeoutMs: 45000
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../../config/environments/staging.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAA+B;IACvD,IAAI,EAAE,SAAS;IACf,GAAG,EAAE;QACH,OAAO,EAAE,6BAA6B;QACtC,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,UAAU;KACxB;IACD,GAAG,EAAE;QACH,OAAO,EAAE,iCAAiC;QAC1C,kBAAkB,EAAE,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,iBAAiB,EAAE;QACpF,SAAS,EAAE,KAAK;KACjB;CACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import type { EnvironmentConfig } from './types';
|
|
3
|
+
declare function loadConfig(): EnvironmentConfig;
|
|
4
|
+
export declare const config: EnvironmentConfig;
|
|
5
|
+
export { loadConfig };
|
|
6
|
+
export type { EnvironmentConfig };
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,iBAAS,UAAU,IAAI,iBAAiB,CA+CvC;AAeD,eAAO,MAAM,MAAM,mBAAe,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
exports.loadConfig = loadConfig;
|
|
5
|
+
require("dotenv/config");
|
|
6
|
+
const default_1 = require("./environments/default");
|
|
7
|
+
function loadConfig() {
|
|
8
|
+
const env = process.env.TEST_ENV ?? 'default';
|
|
9
|
+
let base = default_1.defaultConfig;
|
|
10
|
+
if (env !== 'default') {
|
|
11
|
+
try {
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
13
|
+
const envModule = require(`./environments/${env}`);
|
|
14
|
+
const envConfig = envModule[`${env}Config`];
|
|
15
|
+
base = deepMerge(base, envConfig);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// fall back to default
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// env-var overrides
|
|
22
|
+
if (process.env.WEB_BASE_URL)
|
|
23
|
+
base.web.baseUrl = process.env.WEB_BASE_URL;
|
|
24
|
+
if (process.env.API_BASE_URL)
|
|
25
|
+
base.api.baseUrl = process.env.API_BASE_URL;
|
|
26
|
+
if (process.env.HEADLESS)
|
|
27
|
+
base.web.headless = process.env.HEADLESS !== 'false';
|
|
28
|
+
if (process.env.BROWSER)
|
|
29
|
+
base.web.browserName = process.env.BROWSER;
|
|
30
|
+
if (process.env.MAESTRO_DEVICE)
|
|
31
|
+
base.mobile.deviceId = process.env.MAESTRO_DEVICE;
|
|
32
|
+
if (process.env.FLUTTER_DESKTOP_APP_PATH && base.flutterDesktop) {
|
|
33
|
+
base.flutterDesktop.appPath = process.env.FLUTTER_DESKTOP_APP_PATH;
|
|
34
|
+
}
|
|
35
|
+
if (process.env.FLUTTER_DESKTOP_VM_PORT && base.flutterDesktop) {
|
|
36
|
+
base.flutterDesktop.vmServicePort = Number(process.env.FLUTTER_DESKTOP_VM_PORT);
|
|
37
|
+
}
|
|
38
|
+
if (base.remoteScenarios) {
|
|
39
|
+
const rs = base.remoteScenarios;
|
|
40
|
+
if (process.env.REMOTE_SCENARIOS_URL)
|
|
41
|
+
rs.baseUrl = process.env.REMOTE_SCENARIOS_URL;
|
|
42
|
+
if (process.env.REMOTE_SCENARIOS_PROJECT)
|
|
43
|
+
rs.project = process.env.REMOTE_SCENARIOS_PROJECT;
|
|
44
|
+
if (process.env.REMOTE_SCENARIOS_OUTPUT_DIR)
|
|
45
|
+
rs.outputDir = process.env.REMOTE_SCENARIOS_OUTPUT_DIR;
|
|
46
|
+
rs.filters = rs.filters ?? {};
|
|
47
|
+
if (process.env.REMOTE_SCENARIOS_STORY)
|
|
48
|
+
rs.filters.story = process.env.REMOTE_SCENARIOS_STORY;
|
|
49
|
+
if (process.env.REMOTE_SCENARIOS_REQUIREMENT)
|
|
50
|
+
rs.filters.requirement = process.env.REMOTE_SCENARIOS_REQUIREMENT;
|
|
51
|
+
if (process.env.REMOTE_SCENARIOS_PHASE)
|
|
52
|
+
rs.filters.phase = process.env.REMOTE_SCENARIOS_PHASE;
|
|
53
|
+
if (process.env.REMOTE_SCENARIOS_MODE) {
|
|
54
|
+
rs.filters.mode = process.env.REMOTE_SCENARIOS_MODE;
|
|
55
|
+
}
|
|
56
|
+
if (process.env.REMOTE_SCENARIOS_TAGS)
|
|
57
|
+
rs.filters.tags = process.env.REMOTE_SCENARIOS_TAGS;
|
|
58
|
+
if (process.env.REMOTE_SCENARIOS_FEATURE)
|
|
59
|
+
rs.filters.feature = process.env.REMOTE_SCENARIOS_FEATURE;
|
|
60
|
+
if (process.env.REMOTE_SCENARIOS_Q)
|
|
61
|
+
rs.filters.q = process.env.REMOTE_SCENARIOS_Q;
|
|
62
|
+
if (process.env.REMOTE_SCENARIOS_VALID)
|
|
63
|
+
rs.filters.valid = process.env.REMOTE_SCENARIOS_VALID === 'true';
|
|
64
|
+
}
|
|
65
|
+
return base;
|
|
66
|
+
}
|
|
67
|
+
function deepMerge(base, override) {
|
|
68
|
+
const result = { ...base };
|
|
69
|
+
for (const key of Object.keys(override ?? {})) {
|
|
70
|
+
const ov = override[key];
|
|
71
|
+
if (ov !== null && typeof ov === 'object' && !Array.isArray(ov)) {
|
|
72
|
+
result[key] = deepMerge(result[key], ov);
|
|
73
|
+
}
|
|
74
|
+
else if (ov !== undefined) {
|
|
75
|
+
result[key] = ov;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
exports.config = loadConfig();
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export interface WebConfig {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
headless: boolean;
|
|
4
|
+
browserName: 'chromium' | 'firefox' | 'webkit';
|
|
5
|
+
slowMo?: number;
|
|
6
|
+
viewport?: {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface ApiConfig {
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
defaultCredentials: {
|
|
14
|
+
username: string;
|
|
15
|
+
password: string;
|
|
16
|
+
};
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface MobileConfig {
|
|
20
|
+
deviceId?: string;
|
|
21
|
+
flowsDir: string;
|
|
22
|
+
timeoutMs: number;
|
|
23
|
+
maestroBin?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface DatabaseConfig {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface DesktopConfig {
|
|
29
|
+
agentJar: string;
|
|
30
|
+
javaBin?: string;
|
|
31
|
+
agentPort?: number;
|
|
32
|
+
agentHost?: string;
|
|
33
|
+
defaultTimeoutMs?: number;
|
|
34
|
+
pollIntervalMs?: number;
|
|
35
|
+
screenshotDir?: string;
|
|
36
|
+
jvmArgs?: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface FlutterDesktopConfig {
|
|
39
|
+
/** Absolute path to the built executable (.app bundle on macOS, .exe on Windows). */
|
|
40
|
+
appPath: string;
|
|
41
|
+
/** Per-action timeout, ms. Default 10_000. */
|
|
42
|
+
defaultTimeoutMs?: number;
|
|
43
|
+
/** How long to wait for the VM service URL to appear on stdout. Default 30_000. */
|
|
44
|
+
launchTimeoutMs?: number;
|
|
45
|
+
/** Optional fixed VM service port (passed via --vm-service-port=). Default: ephemeral. */
|
|
46
|
+
vmServicePort?: number;
|
|
47
|
+
/** Extra CLI args appended after the executable. */
|
|
48
|
+
extraArgs?: string[];
|
|
49
|
+
/** Environment variables added to the spawned process. */
|
|
50
|
+
env?: Record<string, string>;
|
|
51
|
+
/** Where failure screenshots are written. Default 'reports/screenshots'. */
|
|
52
|
+
screenshotDir?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface RemoteScenariosFilters {
|
|
55
|
+
/** Story id or comma-separated ids (match any), e.g. "US-007". */
|
|
56
|
+
story?: string;
|
|
57
|
+
/** Requirement id or comma-separated ids; resolved via its stories, e.g. "REQ-001". */
|
|
58
|
+
requirement?: string;
|
|
59
|
+
/** Phase id; restricts to in-scope scenarios, e.g. "P1". */
|
|
60
|
+
phase?: string;
|
|
61
|
+
/** Phase resolution mode. Default 'cumulative'. */
|
|
62
|
+
mode?: 'cumulative' | 'strict';
|
|
63
|
+
/** Cucumber tag expression, e.g. "@smoke and not @wip". */
|
|
64
|
+
tags?: string;
|
|
65
|
+
/** Exact feature name. */
|
|
66
|
+
feature?: string;
|
|
67
|
+
/** Case-insensitive substring over name/feature/content. */
|
|
68
|
+
q?: string;
|
|
69
|
+
/** Filter by gherkin validity. */
|
|
70
|
+
valid?: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface RemoteScenariosConfig {
|
|
73
|
+
/** Base URL of the requ scenario API, e.g. "http://localhost:8788/api". */
|
|
74
|
+
baseUrl: string;
|
|
75
|
+
/** Project slug (required when the API has >1 project loaded). */
|
|
76
|
+
project?: string;
|
|
77
|
+
/** Server-side filters passed to GET /api/scenarios. */
|
|
78
|
+
filters?: RemoteScenariosFilters;
|
|
79
|
+
/** Directory where reconstructed .feature files are written. Default '.remote-features'. */
|
|
80
|
+
outputDir: string;
|
|
81
|
+
}
|
|
82
|
+
export interface EnvironmentConfig {
|
|
83
|
+
name: string;
|
|
84
|
+
web: WebConfig;
|
|
85
|
+
api: ApiConfig;
|
|
86
|
+
mobile: MobileConfig;
|
|
87
|
+
database: DatabaseConfig;
|
|
88
|
+
desktop?: DesktopConfig;
|
|
89
|
+
flutterDesktop?: FlutterDesktopConfig;
|
|
90
|
+
/** Optional: source cucumber scenarios from the requ scenario API instead of local files. */
|
|
91
|
+
remoteScenarios?: RemoteScenariosConfig;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../config/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { APIRequestContext, APIResponse, BrowserContext } from 'playwright';
|
|
2
|
+
import type { EnvironmentConfig } from '../../config/types';
|
|
3
|
+
export declare class ApiDriver {
|
|
4
|
+
private config;
|
|
5
|
+
private _client;
|
|
6
|
+
constructor(config: EnvironmentConfig);
|
|
7
|
+
init(context?: BrowserContext): Promise<void>;
|
|
8
|
+
get client(): APIRequestContext;
|
|
9
|
+
get isInitialized(): boolean;
|
|
10
|
+
get(url: string, options?: Record<string, unknown>): Promise<APIResponse>;
|
|
11
|
+
post(url: string, data?: unknown, options?: Record<string, unknown>): Promise<APIResponse>;
|
|
12
|
+
put(url: string, data?: unknown, options?: Record<string, unknown>): Promise<APIResponse>;
|
|
13
|
+
delete(url: string, options?: Record<string, unknown>): Promise<APIResponse>;
|
|
14
|
+
dispose(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ApiDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiDriver.d.ts","sourceRoot":"","sources":["../../../src/drivers/ApiDriver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAgC,MAAM,YAAY,CAAC;AAC1G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,qBAAa,SAAS;IAGR,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,OAAO,CAAkC;gBAE7B,MAAM,EAAE,iBAAiB;IAEvC,IAAI,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,IAAI,MAAM,IAAI,iBAAiB,CAG9B;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAIzE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAI1F,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAIzF,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAI5E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiDriver = void 0;
|
|
4
|
+
const playwright_1 = require("playwright");
|
|
5
|
+
class ApiDriver {
|
|
6
|
+
config;
|
|
7
|
+
_client = null;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
async init(context) {
|
|
12
|
+
if (context) {
|
|
13
|
+
this._client = context.request;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
this._client = await playwright_1.request.newContext({
|
|
17
|
+
baseURL: this.config.api.baseUrl,
|
|
18
|
+
extraHTTPHeaders: { 'Content-Type': 'application/json' }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
get client() {
|
|
23
|
+
if (!this._client)
|
|
24
|
+
throw new Error('ApiDriver not initialized. Call init() first.');
|
|
25
|
+
return this._client;
|
|
26
|
+
}
|
|
27
|
+
get isInitialized() {
|
|
28
|
+
return this._client !== null;
|
|
29
|
+
}
|
|
30
|
+
async get(url, options) {
|
|
31
|
+
return this.client.get(url, options);
|
|
32
|
+
}
|
|
33
|
+
async post(url, data, options) {
|
|
34
|
+
return this.client.post(url, { data, ...options });
|
|
35
|
+
}
|
|
36
|
+
async put(url, data, options) {
|
|
37
|
+
return this.client.put(url, { data, ...options });
|
|
38
|
+
}
|
|
39
|
+
async delete(url, options) {
|
|
40
|
+
return this.client.delete(url, options);
|
|
41
|
+
}
|
|
42
|
+
async dispose() {
|
|
43
|
+
await this._client?.dispose();
|
|
44
|
+
this._client = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ApiDriver = ApiDriver;
|
|
48
|
+
//# sourceMappingURL=ApiDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiDriver.js","sourceRoot":"","sources":["../../../src/drivers/ApiDriver.ts"],"names":[],"mappings":";;;AAAA,2CAA0G;AAG1G,MAAa,SAAS;IAGA;IAFZ,OAAO,GAA6B,IAAI,CAAC;IAEjD,YAAoB,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAEjD,KAAK,CAAC,IAAI,CAAC,OAAwB;QACjC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,MAAM,oBAAiB,CAAC,UAAU,CAAC;gBAChD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;gBAChC,gBAAgB,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aACzD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,MAAM;QACR,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,OAAiC;QACtD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAc,EAAE,OAAiC;QACvE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,OAAiC;QACtE,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,OAAiC;QACzD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;CACF;AA7CD,8BA6CC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface QueryResult<T> {
|
|
2
|
+
rows: T[];
|
|
3
|
+
rowCount: number;
|
|
4
|
+
}
|
|
5
|
+
export declare abstract class DatabaseDriver {
|
|
6
|
+
abstract connect(): Promise<void>;
|
|
7
|
+
abstract disconnect(): Promise<void>;
|
|
8
|
+
abstract query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
9
|
+
queryOne<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T | null>;
|
|
10
|
+
execute(sql: string, params?: unknown[]): Promise<number>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=DatabaseDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseDriver.d.ts","sourceRoot":"","sources":["../../../src/drivers/DatabaseDriver.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8BAAsB,cAAc;IAClC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAE/F,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKzF,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAIhE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseDriver = void 0;
|
|
4
|
+
class DatabaseDriver {
|
|
5
|
+
async queryOne(sql, params) {
|
|
6
|
+
const result = await this.query(sql, params);
|
|
7
|
+
return result.rows[0] ?? null;
|
|
8
|
+
}
|
|
9
|
+
async execute(sql, params) {
|
|
10
|
+
const result = await this.query(sql, params);
|
|
11
|
+
return result.rowCount;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.DatabaseDriver = DatabaseDriver;
|
|
15
|
+
//# sourceMappingURL=DatabaseDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseDriver.js","sourceRoot":"","sources":["../../../src/drivers/DatabaseDriver.ts"],"names":[],"mappings":";;;AAKA,MAAsB,cAAc;IAKlC,KAAK,CAAC,QAAQ,CAA8B,GAAW,EAAE,MAAkB;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAI,GAAG,EAAE,MAAM,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,MAAkB;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;CACF;AAdD,wCAcC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { EnvironmentConfig } from '../../config/types';
|
|
2
|
+
/**
|
|
3
|
+
* FlutterDesktopDriver
|
|
4
|
+
*
|
|
5
|
+
* Drives a Flutter desktop app (built with `lib/main_test.dart` calling
|
|
6
|
+
* `enableFlutterDriverExtension()`) by:
|
|
7
|
+
* 1. Spawning the executable.
|
|
8
|
+
* 2. Reading the Dart VM service URL printed on stdout.
|
|
9
|
+
* 3. Opening a WebSocket to the VM service.
|
|
10
|
+
* 4. Calling the `ext.flutter.driver` service extension via JSON-RPC.
|
|
11
|
+
*
|
|
12
|
+
* No Dart side process is involved — this is a pure TypeScript client.
|
|
13
|
+
*/
|
|
14
|
+
export type FinderType = 'ByValueKey' | 'ByText' | 'ByType' | 'ByTooltipMessage';
|
|
15
|
+
export interface Finder {
|
|
16
|
+
type: FinderType;
|
|
17
|
+
value: string;
|
|
18
|
+
}
|
|
19
|
+
export type OffsetType = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'center';
|
|
20
|
+
export interface Offset {
|
|
21
|
+
dx: number;
|
|
22
|
+
dy: number;
|
|
23
|
+
}
|
|
24
|
+
export type WaitCondition = 'NoPendingFrames' | 'NoTransientCallbacks' | 'FirstFrameRasterized';
|
|
25
|
+
export declare class FlutterDesktopDriver {
|
|
26
|
+
private readonly cfg;
|
|
27
|
+
private proc;
|
|
28
|
+
private ws;
|
|
29
|
+
private isolateId;
|
|
30
|
+
private nextRpcId;
|
|
31
|
+
private pending;
|
|
32
|
+
private textEntryEmulationEnabled;
|
|
33
|
+
constructor(env: EnvironmentConfig);
|
|
34
|
+
get isLaunched(): boolean;
|
|
35
|
+
launch(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Connect to an already-running Flutter app via its Dart VM service URL.
|
|
38
|
+
* Use instead of `launch()` when the app is already running — e.g.:
|
|
39
|
+
* - **Android**: `adb forward tcp:PORT tcp:PORT`, then connect to `ws://localhost:PORT/TOKEN/ws`
|
|
40
|
+
* - **iOS**: `iproxy PORT PORT DEVICE_UDID`, then connect
|
|
41
|
+
* - **Windows / Linux desktop**: manage the process yourself and pass the URL
|
|
42
|
+
*
|
|
43
|
+
* Accepts either the HTTP form printed by the app (`http://localhost:PORT/TOKEN/`)
|
|
44
|
+
* or the WebSocket form directly (`ws://localhost:PORT/TOKEN/ws`).
|
|
45
|
+
*/
|
|
46
|
+
connect(vmServiceUrl: string, timeoutMs?: number): Promise<void>;
|
|
47
|
+
close(): Promise<void>;
|
|
48
|
+
/** Tap a widget identified by `finder`. */
|
|
49
|
+
tap(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
50
|
+
/** Type `text` into the currently focused text field.
|
|
51
|
+
* Emulation must be enabled BEFORE tapping so that `TextInput.setClient`
|
|
52
|
+
* is captured by the mock — otherwise the mock's _client stays null and
|
|
53
|
+
* enter_text is silently ignored. */
|
|
54
|
+
enterText(finder: Finder, text: string, timeoutMs?: number): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Send a message to the app's `enableFlutterDriverExtension` data handler
|
|
57
|
+
* and return the response string. Use this to invoke app-side actions that
|
|
58
|
+
* cannot be driven through the gesture system (e.g. tapping widgets inside
|
|
59
|
+
* a scrollable that blocks flutter_driver's hitTestable() check).
|
|
60
|
+
*/
|
|
61
|
+
requestData(message: string, timeoutMs?: number): Promise<string>;
|
|
62
|
+
/** Read the text of a Text widget at `finder`. */
|
|
63
|
+
getText(finder: Finder, timeoutMs?: number): Promise<string>;
|
|
64
|
+
/** Wait for `finder` to resolve to an existing widget. */
|
|
65
|
+
waitFor(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
66
|
+
/** Wait until `finder` no longer resolves to any widget. */
|
|
67
|
+
waitForAbsent(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Take a screenshot of the Flutter app's render surface via the
|
|
70
|
+
* `ext.flutter.driver` `screenshot` command. Returns a PNG path.
|
|
71
|
+
*
|
|
72
|
+
* This goes over the same WebSocket as the rest of the driver — no OS-level
|
|
73
|
+
* screen-recording permissions are required, and only the app surface is
|
|
74
|
+
* captured (not the whole desktop).
|
|
75
|
+
*/
|
|
76
|
+
takeScreenshot(name: string): Promise<string>;
|
|
77
|
+
/** Double-tap a widget identified by `finder`. */
|
|
78
|
+
doubleTap(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
79
|
+
/** Long-press a widget identified by `finder`. */
|
|
80
|
+
longPress(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Scroll a Scrollable widget identified by `finder` by (`dx`, `dy`) pixels
|
|
83
|
+
* over `durationMs` milliseconds at `frequency` Hz.
|
|
84
|
+
*/
|
|
85
|
+
scroll(finder: Finder, dx: number, dy: number, durationMs?: number, frequency?: number, timeoutMs?: number): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Scroll until `finder` is visible.
|
|
88
|
+
* `alignment` controls where the widget lands: 0.0 = top edge, 0.5 = center, 1.0 = bottom edge.
|
|
89
|
+
*/
|
|
90
|
+
scrollIntoView(finder: Finder, alignment?: number, timeoutMs?: number): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Clear the text field at `finder` by enabling text-entry emulation,
|
|
93
|
+
* tapping to focus, then setting its value to an empty string.
|
|
94
|
+
*/
|
|
95
|
+
clearText(finder: Finder, timeoutMs?: number): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Non-throwing visibility probe: returns `true` if `finder` resolves within
|
|
98
|
+
* `timeoutMs` (default 500 ms), `false` otherwise. Use for conditional
|
|
99
|
+
* assertions instead of `waitFor` when absence is acceptable.
|
|
100
|
+
*/
|
|
101
|
+
isVisible(finder: Finder, timeoutMs?: number): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Return the screen coordinates of a point on the widget at `finder`.
|
|
104
|
+
* `offsetType` defaults to `'center'`.
|
|
105
|
+
*/
|
|
106
|
+
getOffset(finder: Finder, offsetType?: OffsetType, timeoutMs?: number): Promise<Offset>;
|
|
107
|
+
/**
|
|
108
|
+
* Wait until a predefined Flutter condition is satisfied — the app-level
|
|
109
|
+
* equivalent of Playwright's `page.waitForLoadState()`.
|
|
110
|
+
*
|
|
111
|
+
* `'NoPendingFrames'` — no animation frames scheduled (app is idle)
|
|
112
|
+
* `'NoTransientCallbacks'` — no pending transient callbacks
|
|
113
|
+
* `'FirstFrameRasterized'` — first frame has been rendered
|
|
114
|
+
*/
|
|
115
|
+
waitForCondition(condition: WaitCondition, timeoutMs?: number): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Enable or disable Flutter's frame-sync during driver commands. Set to
|
|
118
|
+
* `false` before triggering heavy animations so the driver does not stall
|
|
119
|
+
* waiting for each frame to settle; restore with `setFrameSync(true)` when
|
|
120
|
+
* done. Mirrors disabling CSS transitions in web tests.
|
|
121
|
+
*/
|
|
122
|
+
setFrameSync(enabled: boolean, timeoutMs?: number): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* NOTE: `isEnabled` (checking whether a widget is interactive) is not part
|
|
125
|
+
* of the `ext.flutter.driver` protocol. Use `requestData()` with an app-side
|
|
126
|
+
* handler that inspects widget state and returns the result as a string.
|
|
127
|
+
*/
|
|
128
|
+
private serializeFinder;
|
|
129
|
+
/** Read stdout/stderr until we see a VM service URL or hit the timeout. */
|
|
130
|
+
private waitForVmServiceUrl;
|
|
131
|
+
private connectWebSocket;
|
|
132
|
+
private onMessage;
|
|
133
|
+
/** Send a JSON-RPC method to the VM service and await the response. */
|
|
134
|
+
private rpc;
|
|
135
|
+
/** Send an `ext.flutter.driver` command on the resolved isolate. */
|
|
136
|
+
private driverCommand;
|
|
137
|
+
private resolveIsolateAndDriverExtension;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=FlutterDesktopDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlutterDesktopDriver.d.ts","sourceRoot":"","sources":["../../../src/drivers/FlutterDesktopDriver.ts"],"names":[],"mappings":"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"}
|