@tvlabs/wdio-service 0.1.0 → 0.1.2

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/src/service.ts ADDED
@@ -0,0 +1,128 @@
1
+ import { SevereServiceError } from 'webdriverio';
2
+ import * as crypto from 'crypto';
3
+ import chalk from 'chalk';
4
+
5
+ import { TVLabsChannel } from './channel.js';
6
+ import { Logger } from './logger.js';
7
+
8
+ import type { Services, Capabilities, Options } from '@wdio/types';
9
+ import type {
10
+ TVLabsCapabilities,
11
+ TVLabsServiceOptions,
12
+ LogLevel,
13
+ } from './types.js';
14
+
15
+ export default class TVLabsService implements Services.ServiceInstance {
16
+ private log: Logger;
17
+
18
+ constructor(
19
+ private _options: TVLabsServiceOptions,
20
+ private _capabilities: Capabilities.ResolvedTestrunnerCapabilities,
21
+ private _config: Options.WebdriverIO,
22
+ ) {
23
+ this.log = new Logger('@tvlabs/wdio-server', this._config.logLevel);
24
+ if (this.attachRequestId()) {
25
+ this.setupRequestId();
26
+ }
27
+ }
28
+
29
+ onPrepare(
30
+ _config: Options.Testrunner,
31
+ param: Capabilities.TestrunnerCapabilities,
32
+ ) {
33
+ if (!Array.isArray(param)) {
34
+ throw new SevereServiceError(
35
+ 'Multi-remote capabilities are not implemented. Contact TV Labs support if you are interested in this feature.',
36
+ );
37
+ }
38
+ }
39
+
40
+ async beforeSession(
41
+ _config: Omit<Options.Testrunner, 'capabilities'>,
42
+ capabilities: TVLabsCapabilities,
43
+ _specs: string[],
44
+ _cid: string,
45
+ ) {
46
+ const channel = new TVLabsChannel(
47
+ this.endpoint(),
48
+ this.reconnectRetries(),
49
+ this.apiKey(),
50
+ this.logLevel(),
51
+ );
52
+
53
+ await channel.connect();
54
+
55
+ capabilities['tvlabs:session_id'] = await channel.newSession(
56
+ capabilities,
57
+ this.retries(),
58
+ );
59
+
60
+ await channel.disconnect();
61
+ }
62
+
63
+ private setupRequestId() {
64
+ const originalTransformRequest = this._config.transformRequest;
65
+
66
+ this._config.transformRequest = (requestOptions: RequestInit) => {
67
+ const requestId = crypto.randomUUID();
68
+ const originalRequestOptions =
69
+ typeof originalTransformRequest === 'function'
70
+ ? originalTransformRequest(requestOptions)
71
+ : requestOptions;
72
+
73
+ if (typeof originalRequestOptions.headers === 'undefined') {
74
+ originalRequestOptions.headers = <HeadersInit>{};
75
+ }
76
+
77
+ this.setRequestHeader(
78
+ originalRequestOptions.headers,
79
+ 'x-request-id',
80
+ requestId,
81
+ );
82
+
83
+ this.log.info(chalk.blue('ATTACHED REQUEST ID'), requestId);
84
+
85
+ return originalRequestOptions;
86
+ };
87
+ }
88
+
89
+ private setRequestHeader(
90
+ headers: RequestInit['headers'],
91
+ header: string,
92
+ value: string,
93
+ ) {
94
+ if (headers instanceof Headers) {
95
+ headers.set(header, value);
96
+ } else if (typeof headers === 'object') {
97
+ if (Array.isArray(headers)) {
98
+ headers.push([header, value]);
99
+ } else {
100
+ headers[header] = value;
101
+ }
102
+ }
103
+ }
104
+
105
+ private endpoint(): string {
106
+ return this._options.endpoint ?? 'wss://tvlabs.ai/appium';
107
+ }
108
+
109
+ private retries(): number {
110
+ return this._options.retries ?? 3;
111
+ }
112
+
113
+ private apiKey(): string {
114
+ return this._options.apiKey;
115
+ }
116
+
117
+ private logLevel(): LogLevel {
118
+ return this._config.logLevel ?? 'info';
119
+ }
120
+
121
+ private attachRequestId(): boolean {
122
+ return this._options.attachRequestId ?? true;
123
+ }
124
+
125
+ private reconnectRetries(): number {
126
+ return this._options.reconnectRetries ?? 5;
127
+ }
128
+ }
package/src/types.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { Capabilities } from '@wdio/types';
2
+
3
+ export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent';
4
+
5
+ export type TVLabsServiceOptions = {
6
+ apiKey: string;
7
+ endpoint?: string;
8
+ retries?: number;
9
+ reconnectRetries?: number;
10
+ attachRequestId?: boolean;
11
+ };
12
+
13
+ export type TVLabsCapabilities =
14
+ Capabilities.RequestedStandaloneCapabilities & {
15
+ 'tvlabs:session_id'?: string;
16
+ 'tvlabs:build'?: string;
17
+ 'tvlabs:constraints'?: {
18
+ platform_key?: string;
19
+ device_type?: string;
20
+ make?: string;
21
+ model?: string;
22
+ year?: string;
23
+ minimum_chromedriver_major_version?: number;
24
+ supports_chromedriver?: boolean;
25
+ };
26
+ 'tvlabs:match_timeout'?: number;
27
+ 'tvlabs:device_timeout'?: number;
28
+ };
29
+
30
+ export type TVLabsSessionRequestEventHandler = (
31
+ response: TVLabsSessionRequestUpdate,
32
+ ) => void;
33
+
34
+ export type TVLabsSessionRequestUpdate = {
35
+ request_id: string;
36
+ session_id: string;
37
+ reason: string;
38
+ };
39
+
40
+ export type TVLabsSessionRequestResponse = {
41
+ request_id: string;
42
+ };
43
+
44
+ export type TVLabsSessionChannelParams = {
45
+ api_key: string;
46
+ };
@@ -1 +0,0 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAKpB,qBAAa,aAAa;IAetB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,GAAG;IAhBb,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAU;IAE/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAOZ;gBAGD,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,MAAM,EAC3B,GAAG,EAAE,MAAM;IAaf,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBxB,UAAU,CACd,YAAY,EAAE,kBAAkB,EAChC,UAAU,EAAE,MAAM,EAClB,KAAK,SAAI,GACR,OAAO,CAAC,MAAM,CAAC;YAWJ,WAAW;YAkBX,cAAc;IAkD5B,OAAO,CAAC,gBAAgB;YAUV,cAAc;YAuBd,IAAI;YAgBJ,IAAI;IAoBlB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;CAG1B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE3E,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,QAAQ,CAAC,eAAe;IAElE,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,OAAO;gBAFP,QAAQ,EAAE,oBAAoB,EAC9B,aAAa,EAAE,YAAY,CAAC,8BAA8B,EAC1D,OAAO,EAAE,OAAO,CAAC,WAAW;IAGtC,SAAS,CACP,OAAO,EAAE,OAAO,CAAC,UAAU,EAC3B,KAAK,EAAE,YAAY,CAAC,sBAAsB;IAStC,aAAa,CACjB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,EACjD,YAAY,EAAE,kBAAkB,EAChC,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,MAAM;IAkBd,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,gBAAgB;CAGzB"}
package/dist/service.js DELETED
@@ -1,35 +0,0 @@
1
- import { SevereServiceError } from 'webdriverio';
2
- import { TVLabsChannel } from './channel.js';
3
- export default class TVLabsService {
4
- _options;
5
- _capabilities;
6
- _config;
7
- constructor(_options, _capabilities, _config) {
8
- this._options = _options;
9
- this._capabilities = _capabilities;
10
- this._config = _config;
11
- }
12
- onPrepare(_config, param) {
13
- if (!Array.isArray(param)) {
14
- throw new SevereServiceError('Multi-remote capabilities are not implemented. Contact TV Labs support if you are interested in this feature.');
15
- }
16
- }
17
- async beforeSession(_config, capabilities, _specs, _cid) {
18
- const channel = new TVLabsChannel(this.endpoint(), this.reconnectRetries(), this.apiKey());
19
- await channel.connect();
20
- capabilities['tvlabs:session_id'] = await channel.newSession(capabilities, this.retries());
21
- await channel.disconnect();
22
- }
23
- endpoint() {
24
- return this._options.endpoint || 'wss://tvlabs.ai/appium';
25
- }
26
- retries() {
27
- return this._options.retries || 3;
28
- }
29
- apiKey() {
30
- return this._options.apiKey;
31
- }
32
- reconnectRetries() {
33
- return this._options.reconnectRetries || 5;
34
- }
35
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC5B,YAAY,CAAC,+BAA+B,GAAG;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,kCAAkC,CAAC,EAAE,MAAM,CAAC;QAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;KACjC,CAAC;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEJ,MAAM,MAAM,gCAAgC,GAAG,CAC7C,QAAQ,EAAE,0BAA0B,KACjC,IAAI,CAAC;AAEV,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
File without changes
File without changes
File without changes
File without changes