@samsara-dev/appwright 0.5.0 → 0.6.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/AGENTS.md ADDED
@@ -0,0 +1,68 @@
1
+ # AGENTS OVERVIEW
2
+
3
+ This document summarizes the Appwright test automation project so autonomous agents understand the environment, capabilities, and workflows before making changes.
4
+
5
+ ## Project Snapshot
6
+
7
+ - **Package name:** `@samsara-dev/appwright`
8
+ - **Language:** TypeScript targeting Node.js ≥ 20.19
9
+ - **Distribution entry:** `dist/index.js` (compiled via `npm run build`)
10
+ - **Primary domains:** Mobile app end-to-end automation on real devices or device farms (BrowserStack, LambdaTest, local emulators)
11
+
12
+ ## Repository Layout
13
+
14
+ - `src/` – TypeScript sources (single source of truth)
15
+ - `dist/` – Generated JavaScript and type declarations; never edit manually
16
+ - `example/` – Sample usage and fixtures
17
+ - `docs/` – Generated documentation assets
18
+ - `.changeset/` – Release notes authored via Changesets
19
+ - `node_modules/` – Managed dependencies (do not commit edits)
20
+
21
+ ## Core Concepts & Types
22
+
23
+ - `Device` class wraps a WebDriver client for mobile-specific flows and is exported from `src/index.ts`.
24
+ - `Locator` utilities hold find strategies and timeout behavior derived from `TimeoutOptions`.
25
+ - Providers (`src/providers/*`) bootstrap sessions for BrowserStack, LambdaTest, local, and emulator contexts.
26
+ - Vision utilities in `src/vision` offer computer-vision-assisted interactions.
27
+
28
+ ## Key Commands
29
+
30
+ ```bash
31
+ npm run build # Compile TypeScript to dist/
32
+ npm test # Run Vitest test suite once
33
+
34
+ npm run lint # Lint via ESLint configuration
35
+ npm run changeset # Create or update release notes
36
+ ```
37
+
38
+ ## Device Helper Summary
39
+
40
+ - `device.getTimeouts()` – Returns the underlying WebDriver timeout configuration (implicit, pageLoad, script, command if available).
41
+ - `device.getWindowRect()` – Exposes the active window rectangle `{ width, height, x, y }` for layout-aware actions.
42
+
43
+ ## Development Guardrails
44
+
45
+ - Always apply edits in `src/` and rebuild; never patch `dist/` directly.
46
+ - Ensure additions remain backward compatible; prefer optional or additive APIs.
47
+ - Run build + tests before concluding any workflow to catch regressions.
48
+ - Use Changesets for versioned changes and keep release notes concise.
49
+
50
+ ## Provider Notes
51
+
52
+ - BrowserStack-specific capabilities live under `src/providers/browserstack` and may take advantage of executor scripts (e.g., camera image injection, keyboard state).
53
+ - LambdaTest support mirrors BrowserStack patterns but with differing executor APIs.
54
+ - Local and emulator providers rely on Appium capabilities configured through project fixtures.
55
+
56
+ ## Telemetry & Vision
57
+
58
+ - Visual trace services are coordinated via `src/visualTrace` to capture screenshots across retries.
59
+ - Vision-based interactions are powered by `@empiricalrun/llm` models; see `Device.beta` helpers for experimental flows.
60
+
61
+ ## Release Workflow
62
+
63
+ 1. Author a Changeset describing user-facing impact.
64
+ 2. Run `npm run build` and `npm test` to validate artifacts.
65
+ 3. Submit PR targeting `main`; CI validates lint/tests.
66
+ 4. Publish via `changeset publish` when ready for release.
67
+
68
+ Agents should adhere to these guardrails to ensure repeatable, secure automation within the Appwright codebase.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # appwright
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 98c9650: Expose `Device.getTimeouts()` along with a lightweight window helper for better session introspection.
8
+
9
+ ## 0.5.1
10
+
11
+ ### Patch Changes
12
+
13
+ - d5b7e84: Apply BrowserStack iOS permission settings after the app install by default, using a worker fixture so sessions start with the requested configuration.
14
+
3
15
  ## 0.5.0
4
16
 
5
17
  ### Minor Changes
@@ -3,6 +3,9 @@ import { AppwrightLocator, DeviceProvider, ExtractType, IosAppSettings, IosPermi
3
3
  import { z } from "zod";
4
4
  import { LLMModel } from "@empiricalrun/llm";
5
5
  import { TestInfo } from "@playwright/test";
6
+ type DeviceTimeouts = Partial<Record<string, number>> & {
7
+ command?: number;
8
+ };
6
9
  export declare class Device {
7
10
  private webDriverClient;
8
11
  private bundleId;
@@ -188,6 +191,19 @@ export declare class Device {
188
191
  setMockCameraView(imagePath: string): Promise<void>;
189
192
  pause(): Promise<void>;
190
193
  waitForTimeout(timeout: number): Promise<void>;
194
+ /**
195
+ * Get the current timeout settings for the WebDriver session.
196
+ */
197
+ getTimeouts(): Promise<DeviceTimeouts>;
198
+ /**
199
+ * Get the current window rectangle dimensions.
200
+ */
201
+ getWindowRect(): Promise<{
202
+ width: number;
203
+ height: number;
204
+ x: number;
205
+ y: number;
206
+ }>;
191
207
  /**
192
208
  * Get a screenshot of the current screen as a base64 encoded string.
193
209
  */
@@ -249,4 +265,5 @@ export declare class Device {
249
265
  */
250
266
  private assertIOSBrowserStack;
251
267
  }
268
+ export {};
252
269
  //# sourceMappingURL=index.d.ts.map
@@ -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,cAAc,EACd,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;IAOf,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IATlB,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,qBAAqB,CAAS;IACtC,OAAO,CAAC,mBAAmB,CAAC,CAAS;gBAG3B,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,WAAW,EAAE,cAAc,EAC3B,QAAQ,EAAE,MAAM,EACxB,cAAc,CAAC,EAAE,cAAc;IAKjC,oBAAoB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIpD,0BAA0B,IAAI,IAAI;IAI5B,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5D,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB/D,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,aAAa;YAQP,QAAQ;IAetB;;OAEG;IACH,qBAAqB,CACnB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,iBAAiB,GACzB,IAAI;IAQP;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvC,OAAO,CAAC,EACN,QAAQ,EACR,YAAY,EACZ,WAAW,GACZ,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAC/B,GAAG,gBAAgB;IAWpB,OAAO,CAAC,MAAM;IAId,IAAI;sBAEQ,MAAM,YACJ;YACR,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,SAAS,CAAC,EAAE;gBACV,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;aACjB,CAAC;SACH,KACA,OAAO,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;gBAItB,CAAC,SAAS,CAAC,CAAC,OAAO,UACvB,MAAM,YACJ;YACR,cAAc,CAAC,EAAE,CAAC,CAAC;YACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,SAAS,CAAC,EAAE;gBACV,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;aACjB,CAAC;SACH,KACA,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;MAG1B;IAEF;;;;;;;OAOG;IACG,KAAK;IAiBX;;;;;;;;;;;OAWG;IAEG,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAoB5C;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,EAAE,KAAa,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,gBAAgB;IAsCnB;;;;;;;;;;;;OAYG;IACH,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,EAAE,KAAa,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,gBAAgB;IAiBnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAI3C;;;;;;;;;OASG;IACH,WAAW,IAAI,QAAQ;IAMjB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM;IAc9B,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM;IAanC;;;;;;;;;;;;;;;;;OAiBG;IAEG,aAAa,CAAC,OAAO,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxD;;;;;;;;;;OAUG;IAEG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAqBzC;;;;;;;;;;;OAWG;IAEG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnD,KAAK;IAmBL,cAAc,CAAC,OAAO,EAAE,MAAM;IAIpC;;OAEG;IAEG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC;;;;;;;;;;OAUG;IAEG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B;;;OAGG;IAEG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlD;;;;;;;;;;;;;;;;;OAiBG;IAEU,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnE;;;;;;;;;;;;;OAaG;IAEU,wBAAwB,CACnC,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC;IAIhB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CAe9B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/device/index.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,8 @@ let Device = (() => {
53
53
  let _setMockCameraView_decorators;
54
54
  let _pause_decorators;
55
55
  let _waitForTimeout_decorators;
56
+ let _getTimeouts_decorators;
57
+ let _getWindowRect_decorators;
56
58
  let _screenshot_decorators;
57
59
  let _scroll_decorators;
58
60
  let _sendKeyStrokes_decorators;
@@ -69,6 +71,8 @@ let Device = (() => {
69
71
  _setMockCameraView_decorators = [utils_1.boxedStep];
70
72
  _pause_decorators = [utils_1.boxedStep];
71
73
  _waitForTimeout_decorators = [utils_1.boxedStep];
74
+ _getTimeouts_decorators = [utils_1.boxedStep];
75
+ _getWindowRect_decorators = [utils_1.boxedStep];
72
76
  _screenshot_decorators = [utils_1.boxedStep];
73
77
  _scroll_decorators = [utils_1.boxedStep];
74
78
  _sendKeyStrokes_decorators = [utils_1.boxedStep];
@@ -82,6 +86,8 @@ let Device = (() => {
82
86
  __esDecorate(this, null, _setMockCameraView_decorators, { kind: "method", name: "setMockCameraView", static: false, private: false, access: { has: obj => "setMockCameraView" in obj, get: obj => obj.setMockCameraView }, metadata: _metadata }, null, _instanceExtraInitializers);
83
87
  __esDecorate(this, null, _pause_decorators, { kind: "method", name: "pause", static: false, private: false, access: { has: obj => "pause" in obj, get: obj => obj.pause }, metadata: _metadata }, null, _instanceExtraInitializers);
84
88
  __esDecorate(this, null, _waitForTimeout_decorators, { kind: "method", name: "waitForTimeout", static: false, private: false, access: { has: obj => "waitForTimeout" in obj, get: obj => obj.waitForTimeout }, metadata: _metadata }, null, _instanceExtraInitializers);
89
+ __esDecorate(this, null, _getTimeouts_decorators, { kind: "method", name: "getTimeouts", static: false, private: false, access: { has: obj => "getTimeouts" in obj, get: obj => obj.getTimeouts }, metadata: _metadata }, null, _instanceExtraInitializers);
90
+ __esDecorate(this, null, _getWindowRect_decorators, { kind: "method", name: "getWindowRect", static: false, private: false, access: { has: obj => "getWindowRect" in obj, get: obj => obj.getWindowRect }, metadata: _metadata }, null, _instanceExtraInitializers);
85
91
  __esDecorate(this, null, _screenshot_decorators, { kind: "method", name: "screenshot", static: false, private: false, access: { has: obj => "screenshot" in obj, get: obj => obj.screenshot }, metadata: _metadata }, null, _instanceExtraInitializers);
86
92
  __esDecorate(this, null, _scroll_decorators, { kind: "method", name: "scroll", static: false, private: false, access: { has: obj => "scroll" in obj, get: obj => obj.scroll }, metadata: _metadata }, null, _instanceExtraInitializers);
87
93
  __esDecorate(this, null, _sendKeyStrokes_decorators, { kind: "method", name: "sendKeyStrokes", static: false, private: false, access: { has: obj => "sendKeyStrokes" in obj, get: obj => obj.sendKeyStrokes }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -501,6 +507,18 @@ let Device = (() => {
501
507
  async waitForTimeout(timeout) {
502
508
  await new Promise((resolve) => setTimeout(resolve, timeout));
503
509
  }
510
+ /**
511
+ * Get the current timeout settings for the WebDriver session.
512
+ */
513
+ async getTimeouts() {
514
+ return (await this.webDriverClient.getTimeouts());
515
+ }
516
+ /**
517
+ * Get the current window rectangle dimensions.
518
+ */
519
+ async getWindowRect() {
520
+ return await this.webDriverClient.getWindowRect();
521
+ }
504
522
  /**
505
523
  * Get a screenshot of the current screen as a base64 encoded string.
506
524
  */
@@ -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,EAGd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAqDnC,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,uRAkFf,CAAC;AA8BH;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;2BACY,gBAAgB,YAAY,aAAa;;;;;;;EAUtE,CAAC"}
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"}
@@ -2,11 +2,49 @@
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");
8
9
  const logger_1 = require("../logger");
9
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
+ }
10
48
  function createPersistentContext(device) {
11
49
  return {
12
50
  device,
@@ -57,6 +95,7 @@ exports.test = test_1.test.extend({
57
95
  // Initialize Visual Trace Service for screenshot capture
58
96
  const visualTraceConfig = testInfo.project.use.visualTrace;
59
97
  device.initializeVisualTrace(testInfo, testInfo.retry, visualTraceConfig);
98
+ await applyIosAppSettings(testInfo.project, device);
60
99
  await deviceProvider.syncTestDetails?.({ name: testInfo.title });
61
100
  await use(device);
62
101
  await device.close();
@@ -89,6 +128,7 @@ exports.test = test_1.test.extend({
89
128
  await workerInfoStore.saveWorkerStartTime(workerIndex, sessionId, providerName, beforeSession, afterSession);
90
129
  device.attachDeviceProvider(deviceProvider);
91
130
  device.enablePersistentStatusSync();
131
+ await applyIosAppSettings(project, device);
92
132
  const context = createPersistentContext(device);
93
133
  persistentDevicesByWorker.set(workerIndex, context);
94
134
  try {
@@ -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;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;CA2FrB"}
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"}
@@ -273,14 +273,11 @@ class BrowserStackDeviceProvider {
273
273
  updateAppSettings = deviceConfig?.updateAppSettings;
274
274
  }
275
275
  if (updateAppSettings && typeof updateAppSettings === "object") {
276
- // Add to bstack:options as per BrowserStack documentation
277
- bstackOptions.updateAppSettings = updateAppSettings;
278
- // Log for debugging (without exposing sensitive data)
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(`iOS app settings configured: permissions=${hasPermissions}, custom_keys=${customKeys.length}`);
280
+ logger_1.logger.log("iOS app settings detected; they will be applied after session start via fixtures.");
284
281
  }
285
282
  }
286
283
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samsara-dev/appwright",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"