@samsara-dev/appwright 0.4.0 → 0.5.1
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 +12 -0
- package/dist/device/index.d.ts +15 -2
- package/dist/device/index.d.ts.map +1 -1
- package/dist/device/index.js +85 -1
- package/dist/fixture/index.d.ts.map +1 -1
- package/dist/fixture/index.js +114 -3
- package/dist/providers/browserstack/index.d.ts.map +1 -1
- package/dist/providers/browserstack/index.js +5 -8
- package/dist/providers/emulator/index.d.ts.map +1 -1
- package/dist/providers/emulator/index.js +1 -1
- package/dist/providers/lambdatest/index.d.ts.map +1 -1
- package/dist/providers/lambdatest/index.js +1 -1
- package/dist/providers/local/index.d.ts.map +1 -1
- package/dist/providers/local/index.js +1 -1
- package/dist/tests/device.spec.js +81 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# appwright
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d5b7e84: Apply BrowserStack iOS permission settings after the app install by default, using a worker fixture so sessions start with the requested configuration.
|
|
8
|
+
|
|
9
|
+
## 0.5.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- c40123e: Add per-test status syncing for persistentDevice so BrowserStack and LambdaTest sessions reflect test names and outcomes.
|
|
14
|
+
|
|
3
15
|
## 0.4.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/device/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Client as WebDriverClient } from "webdriver";
|
|
2
|
-
import { AppwrightLocator, ExtractType, IosAppSettings, IosPermissionSettings, Platform, TimeoutOptions, VisualTraceConfig } from "../types";
|
|
2
|
+
import { AppwrightLocator, DeviceProvider, ExtractType, IosAppSettings, IosPermissionSettings, Platform, TimeoutOptions, VisualTraceConfig } from "../types";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { LLMModel } from "@empiricalrun/llm";
|
|
5
5
|
import { TestInfo } from "@playwright/test";
|
|
@@ -9,7 +9,20 @@ export declare class Device {
|
|
|
9
9
|
private timeoutOpts;
|
|
10
10
|
private provider;
|
|
11
11
|
private visualTraceService?;
|
|
12
|
-
|
|
12
|
+
private deviceProvider?;
|
|
13
|
+
private persistentSyncEnabled;
|
|
14
|
+
private activePersistentKey?;
|
|
15
|
+
constructor(webDriverClient: WebDriverClient, bundleId: string | undefined, timeoutOpts: TimeoutOptions, provider: string, deviceProvider?: DeviceProvider);
|
|
16
|
+
attachDeviceProvider(provider: DeviceProvider): void;
|
|
17
|
+
enablePersistentStatusSync(): void;
|
|
18
|
+
ensurePersistentLifecycle(testInfo: TestInfo): Promise<void>;
|
|
19
|
+
preparePersistentTest(testInfo: TestInfo): Promise<void>;
|
|
20
|
+
finalizePersistentTest(testInfo: TestInfo): Promise<void>;
|
|
21
|
+
private shouldSyncPersistent;
|
|
22
|
+
private persistentKey;
|
|
23
|
+
private mapPlaywrightStatus;
|
|
24
|
+
private failureReason;
|
|
25
|
+
private safeSync;
|
|
13
26
|
/**
|
|
14
27
|
* Initialize Visual Trace Service for screenshot capture during test execution
|
|
15
28
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/device/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,QAAQ,EACR,cAAc,EACd,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAKlB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAO7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,qBAAa,MAAM;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/device/index.ts"],"names":[],"mappings":"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"}
|
package/dist/device/index.js
CHANGED
|
@@ -94,11 +94,95 @@ let Device = (() => {
|
|
|
94
94
|
timeoutOpts;
|
|
95
95
|
provider;
|
|
96
96
|
visualTraceService;
|
|
97
|
-
|
|
97
|
+
deviceProvider;
|
|
98
|
+
persistentSyncEnabled = false;
|
|
99
|
+
activePersistentKey;
|
|
100
|
+
constructor(webDriverClient, bundleId, timeoutOpts, provider, deviceProvider) {
|
|
98
101
|
this.webDriverClient = webDriverClient;
|
|
99
102
|
this.bundleId = bundleId;
|
|
100
103
|
this.timeoutOpts = timeoutOpts;
|
|
101
104
|
this.provider = provider;
|
|
105
|
+
this.deviceProvider = deviceProvider;
|
|
106
|
+
}
|
|
107
|
+
attachDeviceProvider(provider) {
|
|
108
|
+
this.deviceProvider = provider;
|
|
109
|
+
}
|
|
110
|
+
enablePersistentStatusSync() {
|
|
111
|
+
this.persistentSyncEnabled = true;
|
|
112
|
+
}
|
|
113
|
+
async ensurePersistentLifecycle(testInfo) {
|
|
114
|
+
if (!this.shouldSyncPersistent()) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await this.preparePersistentTest(testInfo);
|
|
118
|
+
}
|
|
119
|
+
async preparePersistentTest(testInfo) {
|
|
120
|
+
if (!this.shouldSyncPersistent()) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const key = this.persistentKey(testInfo);
|
|
124
|
+
if (this.activePersistentKey === key) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.activePersistentKey = key;
|
|
128
|
+
await this.safeSync({ name: testInfo.title });
|
|
129
|
+
}
|
|
130
|
+
async finalizePersistentTest(testInfo) {
|
|
131
|
+
if (!this.shouldSyncPersistent()) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const key = this.persistentKey(testInfo);
|
|
135
|
+
if (!this.activePersistentKey) {
|
|
136
|
+
logger_1.logger.warn("finalizePersistentTest called before preparePersistentTest; syncing anyway.");
|
|
137
|
+
}
|
|
138
|
+
else if (this.activePersistentKey !== key) {
|
|
139
|
+
logger_1.logger.warn("finalizePersistentTest received unexpected test key; syncing anyway.");
|
|
140
|
+
}
|
|
141
|
+
const status = this.mapPlaywrightStatus(testInfo.status);
|
|
142
|
+
const reason = status === "failed" ? this.failureReason(testInfo) : undefined;
|
|
143
|
+
await this.safeSync({
|
|
144
|
+
name: testInfo.title,
|
|
145
|
+
status,
|
|
146
|
+
reason,
|
|
147
|
+
});
|
|
148
|
+
this.activePersistentKey = undefined;
|
|
149
|
+
}
|
|
150
|
+
shouldSyncPersistent() {
|
|
151
|
+
return (this.persistentSyncEnabled === true &&
|
|
152
|
+
typeof this.deviceProvider?.syncTestDetails === "function");
|
|
153
|
+
}
|
|
154
|
+
persistentKey(testInfo) {
|
|
155
|
+
return `${testInfo.testId}#${testInfo.retry}`;
|
|
156
|
+
}
|
|
157
|
+
mapPlaywrightStatus(status) {
|
|
158
|
+
switch (status) {
|
|
159
|
+
case "failed":
|
|
160
|
+
case "timedOut":
|
|
161
|
+
case "interrupted":
|
|
162
|
+
return "failed";
|
|
163
|
+
case "passed":
|
|
164
|
+
case "skipped":
|
|
165
|
+
default:
|
|
166
|
+
return "passed";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
failureReason(testInfo) {
|
|
170
|
+
const error = testInfo.errors?.[0];
|
|
171
|
+
if (error?.message) {
|
|
172
|
+
return error.message;
|
|
173
|
+
}
|
|
174
|
+
return testInfo.error?.message;
|
|
175
|
+
}
|
|
176
|
+
async safeSync(details) {
|
|
177
|
+
if (!this.deviceProvider?.syncTestDetails) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
await this.deviceProvider.syncTestDetails(details);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
logger_1.logger.warn("Failed to sync test details", error);
|
|
185
|
+
}
|
|
102
186
|
}
|
|
103
187
|
/**
|
|
104
188
|
* Initialize Visual Trace Service for screenshot capture during test execution
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixture/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixture/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EAMd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA2GnC,KAAK,iBAAiB,GAAG;IACvB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,IAAI,uRA6Ff,CAAC;AA8BH;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;2BACY,gBAAgB,YAAY,aAAa;;;;;;;EAUtE,CAAC"}
|
package/dist/fixture/index.js
CHANGED
|
@@ -2,9 +2,80 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.expect = exports.test = void 0;
|
|
4
4
|
const test_1 = require("@playwright/test");
|
|
5
|
+
const types_1 = require("../types");
|
|
5
6
|
const providers_1 = require("../providers");
|
|
6
7
|
const workerInfo_1 = require("./workerInfo");
|
|
7
8
|
const appium_1 = require("../providers/appium");
|
|
9
|
+
const logger_1 = require("../logger");
|
|
10
|
+
const persistentDevicesByWorker = new Map();
|
|
11
|
+
async function applyIosAppSettings(project, device) {
|
|
12
|
+
if (project.use.platform !== types_1.Platform.IOS) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const deviceConfig = project.use.device;
|
|
16
|
+
if (!deviceConfig || deviceConfig.provider !== "browserstack") {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const browserStackConfig = deviceConfig;
|
|
20
|
+
const envSettingsJson = process.env.APPWRIGHT_BS_UPDATE_APP_SETTINGS_JSON;
|
|
21
|
+
let settings;
|
|
22
|
+
if (envSettingsJson) {
|
|
23
|
+
try {
|
|
24
|
+
settings = JSON.parse(envSettingsJson);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error("APPWRIGHT_BS_UPDATE_APP_SETTINGS_JSON is not valid JSON. Provide a valid JSON string.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
settings = browserStackConfig.updateAppSettings;
|
|
32
|
+
}
|
|
33
|
+
if (!settings || typeof settings !== "object") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
await device.updateAppSettings(settings);
|
|
38
|
+
const hasPermissions = Object.prototype.hasOwnProperty.call(settings, "Permission Settings");
|
|
39
|
+
const customKeys = Object.keys(settings).filter((key) => key !== "Permission Settings");
|
|
40
|
+
if (hasPermissions || customKeys.length > 0) {
|
|
41
|
+
logger_1.logger.log(`iOS app settings applied before tests: permissions=${hasPermissions}, custom_keys=${customKeys.length}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
logger_1.logger.warn("Failed to apply iOS app settings in fixture", error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function createPersistentContext(device) {
|
|
49
|
+
return {
|
|
50
|
+
device,
|
|
51
|
+
activeOperations: 0,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function runWithLifecycle(context, task) {
|
|
55
|
+
context.activeOperations += 1;
|
|
56
|
+
try {
|
|
57
|
+
await task();
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
context.activeOperations -= 1;
|
|
61
|
+
if (context.activeOperations === 0 && context.resolveIdle) {
|
|
62
|
+
context.resolveIdle();
|
|
63
|
+
context.resolveIdle = undefined;
|
|
64
|
+
context.idlePromise = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function waitForLifecycleToComplete(context) {
|
|
69
|
+
if (context.activeOperations === 0) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!context.idlePromise) {
|
|
73
|
+
context.idlePromise = new Promise((resolve) => {
|
|
74
|
+
context.resolveIdle = resolve;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
await context.idlePromise;
|
|
78
|
+
}
|
|
8
79
|
exports.test = test_1.test.extend({
|
|
9
80
|
deviceProvider: async ({}, use, testInfo) => {
|
|
10
81
|
const deviceProvider = (0, providers_1.createDeviceProvider)(testInfo.project);
|
|
@@ -24,6 +95,7 @@ exports.test = test_1.test.extend({
|
|
|
24
95
|
// Initialize Visual Trace Service for screenshot capture
|
|
25
96
|
const visualTraceConfig = testInfo.project.use.visualTrace;
|
|
26
97
|
device.initializeVisualTrace(testInfo, testInfo.retry, visualTraceConfig);
|
|
98
|
+
await applyIosAppSettings(testInfo.project, device);
|
|
27
99
|
await deviceProvider.syncTestDetails?.({ name: testInfo.title });
|
|
28
100
|
await use(device);
|
|
29
101
|
await device.close();
|
|
@@ -54,13 +126,52 @@ exports.test = test_1.test.extend({
|
|
|
54
126
|
const afterSession = new Date();
|
|
55
127
|
const workerInfoStore = new workerInfo_1.WorkerInfoStore();
|
|
56
128
|
await workerInfoStore.saveWorkerStartTime(workerIndex, sessionId, providerName, beforeSession, afterSession);
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
await device
|
|
129
|
+
device.attachDeviceProvider(deviceProvider);
|
|
130
|
+
device.enablePersistentStatusSync();
|
|
131
|
+
await applyIosAppSettings(project, device);
|
|
132
|
+
const context = createPersistentContext(device);
|
|
133
|
+
persistentDevicesByWorker.set(workerIndex, context);
|
|
134
|
+
try {
|
|
135
|
+
await use(device);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
await waitForLifecycleToComplete(context);
|
|
139
|
+
persistentDevicesByWorker.delete(workerIndex);
|
|
140
|
+
await workerInfoStore.saveWorkerEndTime(workerIndex, new Date());
|
|
141
|
+
await device.close();
|
|
142
|
+
}
|
|
60
143
|
},
|
|
61
144
|
{ scope: "worker" },
|
|
62
145
|
],
|
|
63
146
|
});
|
|
147
|
+
exports.test.beforeEach(async ({}, testInfo) => {
|
|
148
|
+
const context = persistentDevicesByWorker.get(testInfo.workerIndex);
|
|
149
|
+
if (!context) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
await runWithLifecycle(context, async () => {
|
|
153
|
+
try {
|
|
154
|
+
await context.device.preparePersistentTest(testInfo);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
logger_1.logger.warn("Failed to prepare persistent test", error);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
exports.test.afterEach(async ({}, testInfo) => {
|
|
162
|
+
const context = persistentDevicesByWorker.get(testInfo.workerIndex);
|
|
163
|
+
if (!context) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
await runWithLifecycle(context, async () => {
|
|
167
|
+
try {
|
|
168
|
+
await context.device.finalizePersistentTest(testInfo);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
logger_1.logger.warn("Failed to finalize persistent test", error);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
64
175
|
/**
|
|
65
176
|
* Function to extend Playwright’s expect assertion capabilities.
|
|
66
177
|
* This adds a new method `toBeVisible` which checks if an element is visible on the screen.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/browserstack/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,eAAe,EACf,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAqDtC,qBAAa,0BAA2B,YAAW,cAAc;IAC/D,OAAO,CAAC,cAAc,CAAC,CAA6B;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,OAAO,CAA+B;gBAG5C,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EACrC,WAAW,EAAE,MAAM,GAAG,SAAS;IAU3B,WAAW;IAwDX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAMlC,OAAO,CAAC,cAAc;YASR,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/browserstack/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,eAAe,EACf,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAqDtC,qBAAa,0BAA2B,YAAW,cAAc;IAC/D,OAAO,CAAC,cAAc,CAAC,CAA6B;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,OAAO,CAA+B;gBAG5C,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EACrC,WAAW,EAAE,MAAM,GAAG,SAAS;IAU3B,WAAW;IAwDX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAMlC,OAAO,CAAC,cAAc;YASR,YAAY;YAiBZ,iBAAiB;YAKjB,yBAAyB;WAK1B,aAAa,CACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAuFlD,eAAe,CAAC,OAAO,EAAE;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IA2BD,OAAO,CAAC,YAAY;CAuFrB"}
|
|
@@ -110,7 +110,7 @@ class BrowserStackDeviceProvider {
|
|
|
110
110
|
const testOptions = {
|
|
111
111
|
expectTimeout: this.project.use.expectTimeout,
|
|
112
112
|
};
|
|
113
|
-
return new device_1.Device(webDriverClient, bundleId, testOptions, this.project.use.device?.provider);
|
|
113
|
+
return new device_1.Device(webDriverClient, bundleId, testOptions, this.project.use.device?.provider, this);
|
|
114
114
|
}
|
|
115
115
|
async getSessionDetails() {
|
|
116
116
|
const data = await getSessionDetails(this.sessionId);
|
|
@@ -273,14 +273,11 @@ class BrowserStackDeviceProvider {
|
|
|
273
273
|
updateAppSettings = deviceConfig?.updateAppSettings;
|
|
274
274
|
}
|
|
275
275
|
if (updateAppSettings && typeof updateAppSettings === "object") {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const u = updateAppSettings;
|
|
280
|
-
const hasPermissions = !!u["Permission Settings"];
|
|
281
|
-
const customKeys = Object.keys(u).filter((k) => k !== "Permission Settings");
|
|
276
|
+
const settings = updateAppSettings;
|
|
277
|
+
const hasPermissions = !!settings["Permission Settings"];
|
|
278
|
+
const customKeys = Object.keys(settings).filter((key) => key !== "Permission Settings");
|
|
282
279
|
if (hasPermissions || customKeys.length > 0) {
|
|
283
|
-
logger_1.logger.log(
|
|
280
|
+
logger_1.logger.log("iOS app settings detected; they will be applied after session start via fixtures.");
|
|
284
281
|
}
|
|
285
282
|
}
|
|
286
283
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/emulator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,qBAAa,gBAAiB,YAAW,cAAc;IAInD,OAAO,CAAC,OAAO;IAHjB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAGT,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EAC7C,WAAW,EAAE,MAAM,GAAG,SAAS;IAS3B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,WAAW;YA8BH,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/emulator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAOtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,qBAAa,gBAAiB,YAAW,cAAc;IAInD,OAAO,CAAC,OAAO;IAHjB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAGT,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EAC7C,WAAW,EAAE,MAAM,GAAG,SAAS;IAS3B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,WAAW;YA8BH,YAAY;YAyBZ,YAAY;CAmC3B"}
|
|
@@ -49,7 +49,7 @@ Follow the steps mentioned in ${androidSimulatorConfigDocLink} to run test on An
|
|
|
49
49
|
const testOptions = {
|
|
50
50
|
expectTimeout,
|
|
51
51
|
};
|
|
52
|
-
return new device_1.Device(webDriverClient, undefined, testOptions, this.project.use.device?.provider);
|
|
52
|
+
return new device_1.Device(webDriverClient, undefined, testOptions, this.project.use.device?.provider, this);
|
|
53
53
|
}
|
|
54
54
|
async createConfig() {
|
|
55
55
|
const platformName = this.project.use.platform;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/lambdatest/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAwDtC,qBAAa,wBAAyB,YAAW,cAAc;IAM3D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,WAAW;IANrB,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,WAAW,CAAgC;gBAGzC,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EACrC,WAAW,EAAE,MAAM,GAAG,SAAS;IASnC,WAAW;IA8DX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAMlC,OAAO,CAAC,cAAc;YASR,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/lambdatest/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAwDtC,qBAAa,wBAAyB,YAAW,cAAc;IAM3D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,WAAW;IANrB,OAAO,CAAC,cAAc,CAAC,CAA2B;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,WAAW,CAAgC;gBAGzC,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EACrC,WAAW,EAAE,MAAM,GAAG,SAAS;IASnC,WAAW;IA8DX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAMlC,OAAO,CAAC,cAAc;YASR,YAAY;WAgBb,aAAa,CACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA6ElD,eAAe,CAAC,OAAO,EAAE;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IA0BD,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,YAAY;CA8CrB"}
|
|
@@ -119,7 +119,7 @@ class LambdaTestDeviceProvider {
|
|
|
119
119
|
const testOptions = {
|
|
120
120
|
expectTimeout: this.project.use.expectTimeout,
|
|
121
121
|
};
|
|
122
|
-
return new device_1.Device(webDriverClient, this.appBundleId, testOptions, this.project.use.device?.provider);
|
|
122
|
+
return new device_1.Device(webDriverClient, this.appBundleId, testOptions, this.project.use.device?.provider, this);
|
|
123
123
|
}
|
|
124
124
|
static async downloadVideo(sessionId, outputDir, fileName) {
|
|
125
125
|
const sessionData = await getSessionDetails(sessionId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAY/C,qBAAa,mBAAoB,YAAW,cAAc;IAItD,OAAO,CAAC,OAAO;IAHjB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAGT,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EAC7C,WAAW,EAAE,MAAM,GAAG,SAAS;IAS3B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,WAAW;YAgBH,YAAY;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EAIf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAY/C,qBAAa,mBAAoB,YAAW,cAAc;IAItD,OAAO,CAAC,OAAO;IAHjB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAGT,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,EAC7C,WAAW,EAAE,MAAM,GAAG,SAAS;IAS3B,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B,WAAW;YAgBH,YAAY;YA0BZ,YAAY;CA6C3B"}
|
|
@@ -40,7 +40,7 @@ class LocalDeviceProvider {
|
|
|
40
40
|
const testOptions = {
|
|
41
41
|
expectTimeout,
|
|
42
42
|
};
|
|
43
|
-
return new device_1.Device(webDriverClient, bundleId, testOptions, this.project.use.device?.provider);
|
|
43
|
+
return new device_1.Device(webDriverClient, bundleId, testOptions, this.project.use.device?.provider, this);
|
|
44
44
|
}
|
|
45
45
|
async createConfig() {
|
|
46
46
|
const platformName = this.project.use.platform;
|
|
@@ -19,6 +19,34 @@ const createDevice = (executeScript = vitest_1.vi.fn()) => {
|
|
|
19
19
|
const device = new device_1.Device(webDriverClient, "com.example.app", { expectTimeout: 1_000 }, "emulator");
|
|
20
20
|
return { device, executeScript };
|
|
21
21
|
};
|
|
22
|
+
const makeTestInfo = (overrides = {}) => {
|
|
23
|
+
return {
|
|
24
|
+
title: "example test",
|
|
25
|
+
status: "passed",
|
|
26
|
+
errors: [],
|
|
27
|
+
error: undefined,
|
|
28
|
+
testId: "test-id",
|
|
29
|
+
retry: 0,
|
|
30
|
+
workerIndex: 0,
|
|
31
|
+
project: { use: {} },
|
|
32
|
+
...overrides,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
const createPersistentDevice = () => {
|
|
36
|
+
const { device } = createDevice();
|
|
37
|
+
const syncTestDetails = vitest_1.vi.fn().mockResolvedValue(undefined);
|
|
38
|
+
const provider = {
|
|
39
|
+
getDevice: vitest_1.vi.fn(),
|
|
40
|
+
syncTestDetails,
|
|
41
|
+
};
|
|
42
|
+
device.attachDeviceProvider(provider);
|
|
43
|
+
device.enablePersistentStatusSync();
|
|
44
|
+
return {
|
|
45
|
+
device,
|
|
46
|
+
syncTestDetails,
|
|
47
|
+
provider,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
22
50
|
(0, vitest_1.describe)("Device", () => {
|
|
23
51
|
(0, vitest_1.describe)("backgroundApp", () => {
|
|
24
52
|
(0, vitest_1.test)("backgrounds indefinitely by default", async () => {
|
|
@@ -113,4 +141,57 @@ const createDevice = (executeScript = vitest_1.vi.fn()) => {
|
|
|
113
141
|
});
|
|
114
142
|
});
|
|
115
143
|
});
|
|
144
|
+
(0, vitest_1.describe)("persistent sync", () => {
|
|
145
|
+
(0, vitest_1.test)("preparePersistentTest sends name once per test", async () => {
|
|
146
|
+
const { device, syncTestDetails } = createPersistentDevice();
|
|
147
|
+
const info = makeTestInfo({ title: "My test", testId: "t-1" });
|
|
148
|
+
await device.preparePersistentTest(info);
|
|
149
|
+
await device.preparePersistentTest(info);
|
|
150
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenCalledTimes(1);
|
|
151
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenCalledWith({ name: "My test" });
|
|
152
|
+
});
|
|
153
|
+
(0, vitest_1.test)("finalizePersistentTest maps failed status and reason", async () => {
|
|
154
|
+
const { device, syncTestDetails } = createPersistentDevice();
|
|
155
|
+
const info = makeTestInfo({
|
|
156
|
+
title: "fails",
|
|
157
|
+
status: "failed",
|
|
158
|
+
errors: [{ message: "boom" }],
|
|
159
|
+
testId: "t-2",
|
|
160
|
+
});
|
|
161
|
+
await device.finalizePersistentTest(info);
|
|
162
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
163
|
+
name: "fails",
|
|
164
|
+
status: "failed",
|
|
165
|
+
reason: "boom",
|
|
166
|
+
}));
|
|
167
|
+
});
|
|
168
|
+
(0, vitest_1.test)("ensurePersistentLifecycle triggers sync for new tests", async () => {
|
|
169
|
+
const { device, syncTestDetails } = createPersistentDevice();
|
|
170
|
+
const first = makeTestInfo({ title: "first", testId: "first", retry: 0 });
|
|
171
|
+
const second = makeTestInfo({
|
|
172
|
+
title: "second",
|
|
173
|
+
testId: "second",
|
|
174
|
+
retry: 0,
|
|
175
|
+
});
|
|
176
|
+
await device.ensurePersistentLifecycle(first);
|
|
177
|
+
await device.ensurePersistentLifecycle(second);
|
|
178
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenNthCalledWith(1, { name: "first" });
|
|
179
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenNthCalledWith(2, { name: "second" });
|
|
180
|
+
});
|
|
181
|
+
(0, vitest_1.test)("finalizePersistentTest defaults skipped to passed without reason", async () => {
|
|
182
|
+
const { device, syncTestDetails } = createPersistentDevice();
|
|
183
|
+
const info = makeTestInfo({
|
|
184
|
+
title: "skipped test",
|
|
185
|
+
status: "skipped",
|
|
186
|
+
testId: "t-3",
|
|
187
|
+
});
|
|
188
|
+
await device.finalizePersistentTest(info);
|
|
189
|
+
(0, vitest_1.expect)(syncTestDetails).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
|
|
190
|
+
name: "skipped test",
|
|
191
|
+
status: "passed",
|
|
192
|
+
}));
|
|
193
|
+
const payload = syncTestDetails.mock.calls[0][0];
|
|
194
|
+
(0, vitest_1.expect)(payload.reason).toBeUndefined();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
116
197
|
});
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,9 +4,11 @@ export declare function boxedStep(target: Function, context: ClassMethodDecorato
|
|
|
4
4
|
device?: {
|
|
5
5
|
takeScreenshot: () => Promise<Buffer>;
|
|
6
6
|
initializeVisualTrace?: (testInfo: any, retryIndex: number, config?: any) => void;
|
|
7
|
+
ensurePersistentLifecycle?: (testInfo: TestInfo) => Promise<void>;
|
|
7
8
|
};
|
|
8
9
|
takeScreenshot?: () => Promise<Buffer>;
|
|
9
10
|
initializeVisualTrace?: (testInfo: any, retryIndex: number, config?: any) => void;
|
|
11
|
+
ensurePersistentLifecycle?: (testInfo: TestInfo) => Promise<void>;
|
|
10
12
|
}, ...args: any) => Promise<any>;
|
|
11
13
|
export declare function validateBuildPath(buildPath: string | undefined, expectedExtension: string): void;
|
|
12
14
|
export declare function getLatestBuildToolsVersions(versions: string[]): string | undefined;
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQlD,wBAAgB,SAAS,CACvB,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,2BAA2B,UAG5B;IACJ,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE;QACP,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,qBAAqB,CAAC,EAAE,CACtB,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,GAAG,KACT,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQlD,wBAAgB,SAAS,CACvB,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,2BAA2B,UAG5B;IACJ,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE;QACP,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,qBAAqB,CAAC,EAAE,CACtB,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,GAAG,KACT,IAAI,CAAC;QACV,yBAAyB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACnE,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,qBAAqB,CAAC,EAAE,CACtB,QAAQ,EAAE,GAAG,EACb,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,GAAG,KACT,IAAI,CAAC;IACV,yBAAyB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,WACQ,GAAG,kBAgFf;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,iBAAiB,EAAE,MAAM,QAoB1B;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuB7E;AAED,wBAAgB,QAAQ,WAEvB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CA2BT;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAST"}
|
package/dist/utils.js
CHANGED
|
@@ -43,6 +43,11 @@ function boxedStep(target, context) {
|
|
|
43
43
|
try {
|
|
44
44
|
const testInfo = test_1.default.info();
|
|
45
45
|
const device = this.device || this;
|
|
46
|
+
if (device &&
|
|
47
|
+
typeof device.ensurePersistentLifecycle === "function" &&
|
|
48
|
+
testInfo) {
|
|
49
|
+
await device.ensurePersistentLifecycle(testInfo);
|
|
50
|
+
}
|
|
46
51
|
// Initialize or reinitialize if needed
|
|
47
52
|
if (device?.initializeVisualTrace && testInfo) {
|
|
48
53
|
const needsInit = (0, visualTrace_1.needsVisualTraceReinitialization)(testInfo.testId, testInfo.retry);
|