appium-safari-driver 4.0.1 → 4.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.
Files changed (78) hide show
  1. package/.github/workflows/publish.js.yml +6 -2
  2. package/CHANGELOG.md +12 -0
  3. package/build/lib/commands/cookies.d.ts +5 -4
  4. package/build/lib/commands/cookies.d.ts.map +1 -1
  5. package/build/lib/commands/cookies.js +3 -5
  6. package/build/lib/commands/cookies.js.map +1 -1
  7. package/build/lib/commands/find.d.ts +9 -8
  8. package/build/lib/commands/find.d.ts.map +1 -1
  9. package/build/lib/commands/find.js +7 -10
  10. package/build/lib/commands/find.js.map +1 -1
  11. package/build/lib/commands/record-screen.d.ts +68 -158
  12. package/build/lib/commands/record-screen.d.ts.map +1 -1
  13. package/build/lib/commands/record-screen.js +35 -75
  14. package/build/lib/commands/record-screen.js.map +1 -1
  15. package/build/lib/desired-caps.d.ts +27 -25
  16. package/build/lib/desired-caps.d.ts.map +1 -1
  17. package/build/lib/desired-caps.js.map +1 -1
  18. package/build/lib/driver.d.ts +18 -54
  19. package/build/lib/driver.d.ts.map +1 -1
  20. package/build/lib/driver.js +25 -20
  21. package/build/lib/driver.js.map +1 -1
  22. package/build/lib/logger.d.ts +1 -1
  23. package/build/lib/logger.d.ts.map +1 -1
  24. package/build/lib/logger.js.map +1 -1
  25. package/build/lib/method-map.d.ts +1 -1
  26. package/build/lib/method-map.d.ts.map +1 -1
  27. package/build/lib/method-map.js +2 -2
  28. package/build/lib/method-map.js.map +1 -1
  29. package/build/lib/safari.d.ts +15 -23
  30. package/build/lib/safari.d.ts.map +1 -1
  31. package/build/lib/safari.js +20 -24
  32. package/build/lib/safari.js.map +1 -1
  33. package/build/lib/utils.d.ts +3 -5
  34. package/build/lib/utils.d.ts.map +1 -1
  35. package/build/lib/utils.js +0 -1
  36. package/build/lib/utils.js.map +1 -1
  37. package/build/test/functional/desktop-driver-e2e-specs.d.ts +2 -0
  38. package/build/test/functional/desktop-driver-e2e-specs.d.ts.map +1 -0
  39. package/build/test/functional/desktop-driver-e2e-specs.js +69 -0
  40. package/build/test/functional/desktop-driver-e2e-specs.js.map +1 -0
  41. package/build/test/functional/mobile-driver-e2e-specs.d.ts +2 -0
  42. package/build/test/functional/mobile-driver-e2e-specs.d.ts.map +1 -0
  43. package/build/test/functional/mobile-driver-e2e-specs.js +95 -0
  44. package/build/test/functional/mobile-driver-e2e-specs.js.map +1 -0
  45. package/build/test/unit/driver-specs.d.ts +2 -0
  46. package/build/test/unit/driver-specs.d.ts.map +1 -0
  47. package/build/test/unit/driver-specs.js +10 -0
  48. package/build/test/unit/driver-specs.js.map +1 -0
  49. package/build/test/unit/utils-specs.d.ts +2 -0
  50. package/build/test/unit/utils-specs.d.ts.map +1 -0
  51. package/build/test/unit/utils-specs.js +43 -0
  52. package/build/test/unit/utils-specs.js.map +1 -0
  53. package/build/test/utils.d.ts +4 -0
  54. package/build/test/utils.d.ts.map +1 -0
  55. package/build/test/utils.js +7 -0
  56. package/build/test/utils.js.map +1 -0
  57. package/build/tsconfig.tsbuildinfo +1 -1
  58. package/lib/commands/cookies.ts +11 -0
  59. package/lib/commands/find.ts +27 -0
  60. package/lib/commands/{record-screen.js → record-screen.ts} +118 -90
  61. package/lib/{desired-caps.js → desired-caps.ts} +6 -1
  62. package/lib/{driver.js → driver.ts} +49 -28
  63. package/lib/{logger.js → logger.ts} +1 -0
  64. package/lib/{method-map.js → method-map.ts} +6 -2
  65. package/lib/{safari.js → safari.ts} +46 -42
  66. package/lib/{utils.js → utils.ts} +5 -4
  67. package/npm-shrinkwrap.json +2847 -281
  68. package/package.json +4 -4
  69. package/test/functional/{desktop-driver-e2e-specs.js → desktop-driver-e2e-specs.ts} +8 -13
  70. package/test/functional/{mobile-driver-e2e-specs.js → mobile-driver-e2e-specs.ts} +10 -12
  71. package/test/unit/driver-specs.ts +9 -0
  72. package/test/unit/{utils-specs.js → utils-specs.ts} +5 -10
  73. package/test/utils.ts +4 -0
  74. package/tsconfig.json +3 -2
  75. package/lib/commands/cookies.js +0 -12
  76. package/lib/commands/find.js +0 -23
  77. package/test/unit/driver-specs.js +0 -15
  78. package/test/utils.js +0 -5
@@ -5,6 +5,12 @@ on:
5
5
  push:
6
6
  branches: [ master ]
7
7
 
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+ issues: write
12
+ id-token: write # to enable use of OIDC for trusted publishing and npm provenance
13
+
8
14
  jobs:
9
15
  build:
10
16
  runs-on: macos-latest
@@ -30,6 +36,4 @@ jobs:
30
36
  - run: npx semantic-release
31
37
  env:
32
38
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
34
39
  name: Release
35
-
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [4.1.0](https://github.com/appium/appium-safari-driver/compare/v4.0.2...v4.1.0) (2025-11-25)
2
+
3
+ ### Features
4
+
5
+ * Migrate driver sources to typescript ([#148](https://github.com/appium/appium-safari-driver/issues/148)) ([c851874](https://github.com/appium/appium-safari-driver/commit/c8518746317289f5db9b27c30639a8b8b42778ae))
6
+
7
+ ## [4.0.2](https://github.com/appium/appium-safari-driver/compare/v4.0.1...v4.0.2) (2025-11-15)
8
+
9
+ ### Miscellaneous Chores
10
+
11
+ * publish via trusted publisher ([#146](https://github.com/appium/appium-safari-driver/issues/146)) ([385a2ad](https://github.com/appium/appium-safari-driver/commit/385a2ad42d9fbd05b9427145b787da0f95c550a6))
12
+
1
13
  ## [4.0.1](https://github.com/appium/appium-safari-driver/compare/v4.0.0...v4.0.1) (2025-08-23)
2
14
 
3
15
  ### Miscellaneous Chores
@@ -1,7 +1,8 @@
1
+ import type { SafariDriver } from '../driver';
1
2
  /**
2
- * @this {SafariDriver}
3
- * @returns {Promise<any>}
3
+ * Delete all cookies visible to the current page.
4
+ *
5
+ * @returns Promise that resolves when cookies are deleted
4
6
  */
5
- export function deleteCookies(this: import("../driver").SafariDriver): Promise<any>;
6
- export type SafariDriver = import("../driver").SafariDriver;
7
+ export declare function deleteCookies(this: SafariDriver): Promise<any>;
7
8
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../lib/commands/cookies.js"],"names":[],"mappings":"AACA;;;GAGG;AACH,uEAFa,OAAO,CAAC,GAAG,CAAC,CAIxB;2BAGY,OAAO,WAAW,EAAE,YAAY"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../lib/commands/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;GAIG;AACH,wBAAsB,aAAa,CAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAErE"}
@@ -2,13 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteCookies = deleteCookies;
4
4
  /**
5
- * @this {SafariDriver}
6
- * @returns {Promise<any>}
5
+ * Delete all cookies visible to the current page.
6
+ *
7
+ * @returns Promise that resolves when cookies are deleted
7
8
  */
8
9
  async function deleteCookies() {
9
10
  return await this.safari.proxy.command('/cookie', 'DELETE');
10
11
  }
11
- /**
12
- * @typedef {import('../driver').SafariDriver} SafariDriver
13
- */
14
12
  //# sourceMappingURL=cookies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../../lib/commands/cookies.js"],"names":[],"mappings":";;AAKA,sCAEC;AAND;;;GAGG;AACI,KAAK,UAAU,aAAa;IACjC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG"}
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../../lib/commands/cookies.ts"],"names":[],"mappings":";;AAOA,sCAEC;AAPD;;;;GAIG;AACI,KAAK,UAAU,aAAa;IACjC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC"}
@@ -1,12 +1,13 @@
1
+ import type { SafariDriver } from '../driver';
1
2
  /**
3
+ * Find element(s) using the specified strategy and selector.
4
+ * This is needed to make lookup by image working.
2
5
  *
3
- * @this {SafariDriver}
4
- * @param {string} strategy
5
- * @param {string} selector
6
- * @param {boolean} mult
7
- * @param {string} [context]
8
- * @returns {Promise<any>}
6
+ * @param strategy - The locator strategy to use
7
+ * @param selector - The selector value
8
+ * @param mult - Whether to find multiple elements
9
+ * @param context - Optional context element ID
10
+ * @returns Promise that resolves to the found element(s)
9
11
  */
10
- export function findElOrEls(this: import("../driver").SafariDriver, strategy: string, selector: string, mult: boolean, context?: string): Promise<any>;
11
- export type SafariDriver = import("../driver").SafariDriver;
12
+ export declare function findElOrEls(this: SafariDriver, strategy: string, selector: string, mult: boolean, context?: string): Promise<any>;
12
13
  //# sourceMappingURL=find.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../lib/commands/find.js"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,8EANW,MAAM,YACN,MAAM,QACN,OAAO,YACP,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CAQxB;2BAGY,OAAO,WAAW,EAAE,YAAY"}
1
+ {"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,GAAG,CAAC,CAMd"}
@@ -2,15 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findElOrEls = findElOrEls;
4
4
  const support_1 = require("appium/support");
5
- // This is needed to make lookup by image working
6
5
  /**
6
+ * Find element(s) using the specified strategy and selector.
7
+ * This is needed to make lookup by image working.
7
8
  *
8
- * @this {SafariDriver}
9
- * @param {string} strategy
10
- * @param {string} selector
11
- * @param {boolean} mult
12
- * @param {string} [context]
13
- * @returns {Promise<any>}
9
+ * @param strategy - The locator strategy to use
10
+ * @param selector - The selector value
11
+ * @param mult - Whether to find multiple elements
12
+ * @param context - Optional context element ID
13
+ * @returns Promise that resolves to the found element(s)
14
14
  */
15
15
  async function findElOrEls(strategy, selector, mult, context) {
16
16
  const endpoint = `/element${context ? `/${support_1.util.unwrapElement(context)}/element` : ''}${mult ? 's' : ''}`;
@@ -19,7 +19,4 @@ async function findElOrEls(strategy, selector, mult, context) {
19
19
  value: selector,
20
20
  });
21
21
  }
22
- /**
23
- * @typedef {import('../driver').SafariDriver} SafariDriver
24
- */
25
22
  //# sourceMappingURL=find.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../lib/commands/find.js"],"names":[],"mappings":";;AAYA,kCAMC;AAlBD,4CAAsC;AAEtC,iDAAiD;AACjD;;;;;;;;GAQG;AACI,KAAK,UAAU,WAAW,CAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO;IAClE,MAAM,QAAQ,GAAG,WAAW,OAAO,CAAC,CAAC,CAAC,IAAI,cAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACzG,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE;QACvD,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG"}
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../lib/commands/find.ts"],"names":[],"mappings":";;AAaA,kCAYC;AAzBD,4CAAsC;AAGtC;;;;;;;;;GASG;AACI,KAAK,UAAU,WAAW,CAE/B,QAAgB,EAChB,QAAgB,EAChB,IAAa,EACb,OAAgB;IAEhB,MAAM,QAAQ,GAAG,WAAW,OAAO,CAAC,CAAC,CAAC,IAAI,cAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACzG,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE;QACvD,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;AACL,CAAC"}
@@ -1,178 +1,88 @@
1
- /**
2
- * @typedef {Object} StartRecordingOptions
3
- *
4
- * @property {string} codec [hevc] - Specifies the codec type: "h264" or "hevc"
5
- * @property {string} display [internal] - Supports "internal" or "external". Default is "internal"
6
- * @property {string} mask - For non-rectangular displays, handle the mask by policy:
7
- * - ignored: The mask is ignored and the unmasked framebuffer is saved.
8
- * - alpha: Not supported, but retained for compatibility; the mask is rendered black.
9
- * - black: The mask is rendered black.
10
- * @property {string|number} timeLimit [600] - The maximum recording time, in seconds. The default
11
- * value is 600 seconds (10 minutes).
12
- * @property {boolean} forceRestart [true] - Whether to ignore the call if a screen recording is currently running
13
- * (`false`) or to start a new recording immediately and terminate the existing one if running (`true`).
14
- */
15
- /**
16
- * Record the Simulator's display in background while the automated test is running.
17
- * This method uses `xcrun simctl io recordVideo` helper under the hood.
18
- * Check the output of `xcrun simctl io` command for more details.
19
- *
20
- * @this {SafariDriver}
21
- * @param {StartRecordingOptions} options - The available options.
22
- * @this {import('../driver').SafariDriver}
23
- * @throws {Error} If screen recording has failed to start or is not supported for the destination device.
24
- */
25
- export function startRecordingScreen(this: import("../driver").SafariDriver, options: StartRecordingOptions): Promise<void>;
26
- export class startRecordingScreen {
27
- /**
28
- * @typedef {Object} StartRecordingOptions
29
- *
30
- * @property {string} codec [hevc] - Specifies the codec type: "h264" or "hevc"
31
- * @property {string} display [internal] - Supports "internal" or "external". Default is "internal"
32
- * @property {string} mask - For non-rectangular displays, handle the mask by policy:
1
+ import type { AppiumLogger } from '@appium/types';
2
+ import type { SafariDriver } from '../driver';
3
+ interface ScreenRecorderOptions {
4
+ codec?: string;
5
+ display?: string;
6
+ mask?: string;
7
+ timeLimit?: string | number;
8
+ }
9
+ export declare class ScreenRecorder {
10
+ private log;
11
+ private _process;
12
+ private _udid;
13
+ private _videoPath;
14
+ private _codec?;
15
+ private _display?;
16
+ private _mask?;
17
+ private _timeLimitMs;
18
+ private _timer;
19
+ constructor(udid: string, videoPath: string, log: AppiumLogger, opts?: ScreenRecorderOptions);
20
+ getVideoPath(): Promise<string>;
21
+ get isRunning(): boolean;
22
+ start(): Promise<void>;
23
+ stop(force?: boolean): Promise<string>;
24
+ private _enforceTermination;
25
+ }
26
+ export interface StartRecordingOptions {
27
+ /** Specifies the codec type: "h264" or "hevc" */
28
+ codec?: string;
29
+ /** Supports "internal" or "external". Default is "internal" */
30
+ display?: string;
31
+ /** For non-rectangular displays, handle the mask by policy:
33
32
  * - ignored: The mask is ignored and the unmasked framebuffer is saved.
34
33
  * - alpha: Not supported, but retained for compatibility; the mask is rendered black.
35
34
  * - black: The mask is rendered black.
36
- * @property {string|number} timeLimit [600] - The maximum recording time, in seconds. The default
37
- * value is 600 seconds (10 minutes).
38
- * @property {boolean} forceRestart [true] - Whether to ignore the call if a screen recording is currently running
39
- * (`false`) or to start a new recording immediately and terminate the existing one if running (`true`).
40
35
  */
41
- /**
42
- * Record the Simulator's display in background while the automated test is running.
43
- * This method uses `xcrun simctl io recordVideo` helper under the hood.
44
- * Check the output of `xcrun simctl io` command for more details.
45
- *
46
- * @this {SafariDriver}
47
- * @param {StartRecordingOptions} options - The available options.
48
- * @this {import('../driver').SafariDriver}
49
- * @throws {Error} If screen recording has failed to start or is not supported for the destination device.
36
+ mask?: string;
37
+ /** The maximum recording time, in seconds. The default value is 600 seconds (10 minutes). */
38
+ timeLimit?: string | number;
39
+ /** Whether to ignore the call if a screen recording is currently running
40
+ * (`false`) or to start a new recording immediately and terminate the existing one if running (`true`).
50
41
  */
51
- constructor(this: import("../driver").SafariDriver, options: StartRecordingOptions);
52
- _screenRecorder: ScreenRecorder;
42
+ forceRestart?: boolean;
53
43
  }
54
44
  /**
55
- * @typedef {Object} StopRecordingOptions
45
+ * Record the Simulator's display in background while the automated test is running.
46
+ * This method uses `xcrun simctl io recordVideo` helper under the hood.
47
+ * Check the output of `xcrun simctl io` command for more details.
56
48
  *
57
- * @property {string} remotePath - The path to the remote location, where the resulting video should be uploaded.
58
- * The following protocols are supported: http/https, ftp.
59
- * Null or empty string value (the default setting) means the content of resulting
60
- * file should be encoded as Base64 and passed as the endpoint response value.
61
- * An exception will be thrown if the generated media file is too big to
62
- * fit into the available process memory.
63
- * @property {string} user - The name of the user for the remote authentication.
64
- * @property {string} pass - The password for the remote authentication.
65
- * @property {string} method - The http multipart upload method name. The 'PUT' one is used by default.
66
- * @property {Object} headers - Additional headers mapping for multipart http(s) uploads
67
- * @property {string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for
68
- * http(s) uploads
69
- * @property {Object|[string, string][]} formFields - Additional form fields for multipart http(s) uploads
49
+ * @param options - The available options.
50
+ * @throws {Error} If screen recording has failed to start or is not supported for the destination device.
70
51
  */
52
+ export declare function startRecordingScreen(this: SafariDriver, options?: StartRecordingOptions): Promise<void>;
53
+ export interface StopRecordingOptions {
54
+ /** The path to the remote location, where the resulting video should be uploaded.
55
+ * The following protocols are supported: http/https, ftp.
56
+ * Null or empty string value (the default setting) means the content of resulting
57
+ * file should be encoded as Base64 and passed as the endpoint response value.
58
+ * An exception will be thrown if the generated media file is too big to
59
+ * fit into the available process memory.
60
+ */
61
+ remotePath?: string;
62
+ /** The name of the user for the remote authentication. */
63
+ user?: string;
64
+ /** The password for the remote authentication. */
65
+ pass?: string;
66
+ /** The http multipart upload method name. The 'PUT' one is used by default. */
67
+ method?: string;
68
+ /** Additional headers mapping for multipart http(s) uploads */
69
+ headers?: Record<string, string>;
70
+ /** The name of the form field, where the file content BLOB should be stored for http(s) uploads */
71
+ fileFieldName?: string;
72
+ /** Additional form fields for multipart http(s) uploads */
73
+ formFields?: Record<string, string> | Array<[string, string]>;
74
+ }
71
75
  /**
72
76
  * Stop recording the screen.
73
77
  * If no screen recording has been started before then the method returns an empty string.
74
78
  *
75
- * @this {SafariDriver}
76
- * @param {StopRecordingOptions} options - The available options.
77
- * @returns {Promise<string>} Base64-encoded content of the recorded media file if 'remotePath'
79
+ * @param options - The available options.
80
+ * @returns Base64-encoded content of the recorded media file if 'remotePath'
78
81
  * parameter is falsy or an empty string.
79
- * @this {import('../driver').SafariDriver}
80
82
  * @throws {Error} If there was an error while getting the name of a media file
81
83
  * or the file content cannot be uploaded to the remote location
82
84
  * or screen recording is not supported on the device under test.
83
85
  */
84
- export function stopRecordingScreen(this: import("../driver").SafariDriver, options: StopRecordingOptions): Promise<string>;
85
- export type StartRecordingOptions = {
86
- /**
87
- * [hevc] - Specifies the codec type: "h264" or "hevc"
88
- */
89
- codec: string;
90
- /**
91
- * [internal] - Supports "internal" or "external". Default is "internal"
92
- */
93
- display: string;
94
- /**
95
- * - For non-rectangular displays, handle the mask by policy:
96
- * - ignored: The mask is ignored and the unmasked framebuffer is saved.
97
- * - alpha: Not supported, but retained for compatibility; the mask is rendered black.
98
- * - black: The mask is rendered black.
99
- */
100
- mask: string;
101
- /**
102
- * [600] - The maximum recording time, in seconds. The default
103
- * value is 600 seconds (10 minutes).
104
- */
105
- timeLimit: string | number;
106
- /**
107
- * [true] - Whether to ignore the call if a screen recording is currently running
108
- * (`false`) or to start a new recording immediately and terminate the existing one if running (`true`).
109
- */
110
- forceRestart: boolean;
111
- };
112
- export type StopRecordingOptions = {
113
- /**
114
- * - The path to the remote location, where the resulting video should be uploaded.
115
- * The following protocols are supported: http/https, ftp.
116
- * Null or empty string value (the default setting) means the content of resulting
117
- * file should be encoded as Base64 and passed as the endpoint response value.
118
- * An exception will be thrown if the generated media file is too big to
119
- * fit into the available process memory.
120
- */
121
- remotePath: string;
122
- /**
123
- * - The name of the user for the remote authentication.
124
- */
125
- user: string;
126
- /**
127
- * - The password for the remote authentication.
128
- */
129
- pass: string;
130
- /**
131
- * - The http multipart upload method name. The 'PUT' one is used by default.
132
- */
133
- method: string;
134
- /**
135
- * - Additional headers mapping for multipart http(s) uploads
136
- */
137
- headers: any;
138
- /**
139
- * [file] - The name of the form field, where the file content BLOB should be stored for
140
- * http(s) uploads
141
- */
142
- fileFieldName: string;
143
- /**
144
- * - Additional form fields for multipart http(s) uploads
145
- */
146
- formFields: any | [string, string][];
147
- };
148
- export type SafariDriver = import("../driver").SafariDriver;
149
- declare class ScreenRecorder {
150
- /**
151
- * @param {string} udid
152
- * @param {string} videoPath
153
- * @param {import('@appium/types').AppiumLogger} log
154
- * @param {{codec?: string, display?: string, mask?: string, timeLimit?: string|number}} [opts={}]
155
- */
156
- constructor(udid: string, videoPath: string, log: import("@appium/types").AppiumLogger, opts?: {
157
- codec?: string;
158
- display?: string;
159
- mask?: string;
160
- timeLimit?: string | number;
161
- });
162
- log: import("@appium/types").AppiumLogger;
163
- _process: any;
164
- _udid: string;
165
- _videoPath: string;
166
- _codec: string | undefined;
167
- _display: string | undefined;
168
- _mask: string | undefined;
169
- _timeLimitMs: number;
170
- _timer: NodeJS.Timeout | null;
171
- getVideoPath(): Promise<string>;
172
- get isRunning(): boolean;
173
- _enforceTermination(): Promise<string>;
174
- start(): Promise<void>;
175
- stop(force?: boolean): Promise<string>;
176
- }
86
+ export declare function stopRecordingScreen(this: SafariDriver, options?: StopRecordingOptions): Promise<string>;
177
87
  export {};
178
88
  //# sourceMappingURL=record-screen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"record-screen.d.ts","sourceRoot":"","sources":["../../../lib/commands/record-screen.js"],"names":[],"mappings":"AAsNA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;GASG;AACH,sFAJW,qBAAqB,iBA6C/B;;IAlED;;;;;;;;;;;;;OAaG;IAEH;;;;;;;;;OASG;IACH,6DAJW,qBAAqB,EA6C/B;IAxBC,gCAA2B;;AA0B7B;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;GAYG;AACH,qFARW,oBAAoB,GAClB,OAAO,CAAC,MAAM,CAAC,CAwB3B;;;;;WAjHa,MAAM;;;;aACN,MAAM;;;;;;;UACN,MAAM;;;;;eAIN,MAAM,GAAC,MAAM;;;;;kBAEb,OAAO;;;;;;;;;;;gBA4DP,MAAM;;;;UAMN,MAAM;;;;UACN,MAAM;;;;YACN,MAAM;;;;;;;;;mBAEN,MAAM;;;;gBAEN,MAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;;2BAoC1B,OAAO,WAAW,EAAE,YAAY;AA/R7C;IACE;;;;;OAKG;IACH,kBALW,MAAM,aACN,MAAM,OACN,OAAO,eAAe,EAAE,YAAY,SACpC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAC,MAAM,CAAA;KAAC,EAkBtF;IAfC,0CAAc;IACd,cAAoB;IACpB,cAAiB;IACjB,mBAA2B;IAC3B,2BAAwB;IACxB,6BAA4B;IAC5B,0BAAsB;IACtB,qBAAyC;IAOzC,8BAAkB;IAGpB,gCAMC;IAED,yBAEC;IAED,uCAcC;IAED,uBA8DC;IAED,uCAuBC;CACF"}
1
+ {"version":3,"file":"record-screen.d.ts","sourceRoot":"","sources":["../../../lib/commands/record-screen.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAiD9C,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,MAAM,CAA+B;gBAEhC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,GAAE,qBAA0B;IAe3F,YAAY,IAAK,OAAO,CAAC,MAAM,CAAC;IAQtC,IAAI,SAAS,IAAK,OAAO,CAExB;IAEK,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAgEvB,IAAI,CAAE,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,MAAM,CAAC;YA6BtC,mBAAmB;CAelC;AA0BD,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ScreenRecorder = void 0;
6
7
  exports.startRecordingScreen = startRecordingScreen;
7
8
  exports.stopRecordingScreen = stopRecordingScreen;
8
9
  const lodash_1 = __importDefault(require("lodash"));
@@ -14,13 +15,6 @@ const STARTUP_TIMEOUT_MS = 10 * 1000;
14
15
  const DEFAULT_TIME_LIMIT_MS = 60 * 10 * 1000; // 10 minutes
15
16
  const PROCESS_SHUTDOWN_TIMEOUT_MS = 10 * 1000;
16
17
  const DEFAULT_EXT = '.mp4';
17
- /**
18
- *
19
- * @param {string} localFile
20
- * @param {string|null} remotePath
21
- * @param {Object} uploadOptions
22
- * @returns
23
- */
24
18
  async function uploadRecordedMedia(localFile, remotePath = null, uploadOptions = {}) {
25
19
  if (lodash_1.default.isEmpty(remotePath) || !remotePath) {
26
20
  return (await support_1.util.toInMemoryBase64(localFile)).toString();
@@ -48,28 +42,28 @@ process.on('exit', () => {
48
42
  }
49
43
  });
50
44
  class ScreenRecorder {
51
- /**
52
- * @param {string} udid
53
- * @param {string} videoPath
54
- * @param {import('@appium/types').AppiumLogger} log
55
- * @param {{codec?: string, display?: string, mask?: string, timeLimit?: string|number}} [opts={}]
56
- */
45
+ log;
46
+ _process = null;
47
+ _udid;
48
+ _videoPath;
49
+ _codec;
50
+ _display;
51
+ _mask;
52
+ _timeLimitMs = DEFAULT_TIME_LIMIT_MS;
53
+ _timer = null;
57
54
  constructor(udid, videoPath, log, opts = {}) {
58
55
  this.log = log;
59
- this._process = null;
60
56
  this._udid = udid;
61
57
  this._videoPath = videoPath;
62
58
  this._codec = opts.codec;
63
59
  this._display = opts.display;
64
60
  this._mask = opts.mask;
65
- this._timeLimitMs = DEFAULT_TIME_LIMIT_MS;
66
61
  if (opts.timeLimit) {
67
62
  const timeLimitMs = parseInt(String(opts.timeLimit), 10);
68
63
  if (timeLimitMs > 0) {
69
64
  this._timeLimitMs = timeLimitMs * 1000;
70
65
  }
71
66
  }
72
- this._timer = null;
73
67
  }
74
68
  async getVideoPath() {
75
69
  if (await support_1.fs.exists(this._videoPath)) {
@@ -81,22 +75,6 @@ class ScreenRecorder {
81
75
  get isRunning() {
82
76
  return !!(this._process?.isRunning);
83
77
  }
84
- async _enforceTermination() {
85
- if (this.isRunning) {
86
- this.log.debug('Force-stopping the currently running video recording');
87
- try {
88
- await /** @type {import('teen_process').SubProcess} */ (this._process).stop('SIGKILL');
89
- }
90
- catch { }
91
- }
92
- this._process = null;
93
- const videoPath = await this.getVideoPath();
94
- if (videoPath) {
95
- await support_1.fs.rimraf(videoPath);
96
- VIDEO_FILES.delete(videoPath);
97
- }
98
- return '';
99
- }
100
78
  async start() {
101
79
  const args = [
102
80
  this._udid, 'recordVideo'
@@ -173,8 +151,11 @@ class ScreenRecorder {
173
151
  this.log.debug('Screen recording is not running. Returning the recently recorded video');
174
152
  return await this.getVideoPath();
175
153
  }
154
+ if (!this._process) {
155
+ throw new Error('Screen recording process is not available');
156
+ }
176
157
  try {
177
- await /** @type {import('teen_process').SubProcess} */ (this._process).stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT_MS);
158
+ await this._process.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT_MS);
178
159
  }
179
160
  catch {
180
161
  await this._enforceTermination();
@@ -182,7 +163,24 @@ class ScreenRecorder {
182
163
  }
183
164
  return await this.getVideoPath();
184
165
  }
166
+ async _enforceTermination() {
167
+ if (this.isRunning && this._process) {
168
+ this.log.debug('Force-stopping the currently running video recording');
169
+ try {
170
+ await this._process.stop('SIGKILL');
171
+ }
172
+ catch { }
173
+ }
174
+ this._process = null;
175
+ const videoPath = await this.getVideoPath();
176
+ if (videoPath) {
177
+ await support_1.fs.rimraf(videoPath);
178
+ VIDEO_FILES.delete(videoPath);
179
+ }
180
+ return '';
181
+ }
185
182
  }
183
+ exports.ScreenRecorder = ScreenRecorder;
186
184
  async function extractSimulatorUdid(caps) {
187
185
  if (caps['safari:useSimulator'] === false) {
188
186
  return null;
@@ -203,28 +201,12 @@ async function extractSimulatorUdid(caps) {
203
201
  }
204
202
  return null;
205
203
  }
206
- /**
207
- * @typedef {Object} StartRecordingOptions
208
- *
209
- * @property {string} codec [hevc] - Specifies the codec type: "h264" or "hevc"
210
- * @property {string} display [internal] - Supports "internal" or "external". Default is "internal"
211
- * @property {string} mask - For non-rectangular displays, handle the mask by policy:
212
- * - ignored: The mask is ignored and the unmasked framebuffer is saved.
213
- * - alpha: Not supported, but retained for compatibility; the mask is rendered black.
214
- * - black: The mask is rendered black.
215
- * @property {string|number} timeLimit [600] - The maximum recording time, in seconds. The default
216
- * value is 600 seconds (10 minutes).
217
- * @property {boolean} forceRestart [true] - Whether to ignore the call if a screen recording is currently running
218
- * (`false`) or to start a new recording immediately and terminate the existing one if running (`true`).
219
- */
220
204
  /**
221
205
  * Record the Simulator's display in background while the automated test is running.
222
206
  * This method uses `xcrun simctl io recordVideo` helper under the hood.
223
207
  * Check the output of `xcrun simctl io` command for more details.
224
208
  *
225
- * @this {SafariDriver}
226
- * @param {StartRecordingOptions} options - The available options.
227
- * @this {import('../driver').SafariDriver}
209
+ * @param options - The available options.
228
210
  * @throws {Error} If screen recording has failed to start or is not supported for the destination device.
229
211
  */
230
212
  async function startRecordingScreen(options) {
@@ -262,32 +244,13 @@ async function startRecordingScreen(options) {
262
244
  throw e;
263
245
  }
264
246
  }
265
- /**
266
- * @typedef {Object} StopRecordingOptions
267
- *
268
- * @property {string} remotePath - The path to the remote location, where the resulting video should be uploaded.
269
- * The following protocols are supported: http/https, ftp.
270
- * Null or empty string value (the default setting) means the content of resulting
271
- * file should be encoded as Base64 and passed as the endpoint response value.
272
- * An exception will be thrown if the generated media file is too big to
273
- * fit into the available process memory.
274
- * @property {string} user - The name of the user for the remote authentication.
275
- * @property {string} pass - The password for the remote authentication.
276
- * @property {string} method - The http multipart upload method name. The 'PUT' one is used by default.
277
- * @property {Object} headers - Additional headers mapping for multipart http(s) uploads
278
- * @property {string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for
279
- * http(s) uploads
280
- * @property {Object|[string, string][]} formFields - Additional form fields for multipart http(s) uploads
281
- */
282
247
  /**
283
248
  * Stop recording the screen.
284
249
  * If no screen recording has been started before then the method returns an empty string.
285
250
  *
286
- * @this {SafariDriver}
287
- * @param {StopRecordingOptions} options - The available options.
288
- * @returns {Promise<string>} Base64-encoded content of the recorded media file if 'remotePath'
251
+ * @param options - The available options.
252
+ * @returns Base64-encoded content of the recorded media file if 'remotePath'
289
253
  * parameter is falsy or an empty string.
290
- * @this {import('../driver').SafariDriver}
291
254
  * @throws {Error} If there was an error while getting the name of a media file
292
255
  * or the file content cannot be uploaded to the remote location
293
256
  * or screen recording is not supported on the device under test.
@@ -307,9 +270,6 @@ async function stopRecordingScreen(options) {
307
270
  const { size } = await support_1.fs.stat(videoPath);
308
271
  this.log.debug(`The size of the resulting screen recording is ${support_1.util.toReadableSizeString(size)}`);
309
272
  }
310
- return await uploadRecordedMedia(videoPath, options?.remotePath, options);
273
+ return await uploadRecordedMedia(videoPath, options?.remotePath ?? null, options ?? {});
311
274
  }
312
- /**
313
- * @typedef {import('../driver').SafariDriver} SafariDriver
314
- */
315
275
  //# sourceMappingURL=record-screen.js.map