@serenity-js/playwright-test 3.36.2 → 3.37.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 +21 -0
- package/README.md +140 -157
- package/lib/api/serenity-fixtures.d.ts +103 -22
- package/lib/api/serenity-fixtures.d.ts.map +1 -1
- package/lib/api/test-api.d.ts +41 -5
- package/lib/api/test-api.d.ts.map +1 -1
- package/lib/api/test-api.js +62 -14
- package/lib/api/test-api.js.map +1 -1
- package/package.json +7 -6
- package/src/api/serenity-fixtures.ts +106 -21
- package/src/api/test-api.ts +81 -29
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
Ability,
|
|
3
|
+
Actor,
|
|
2
4
|
Cast,
|
|
3
5
|
ClassDescription,
|
|
4
6
|
Duration,
|
|
@@ -6,8 +8,9 @@ import type {
|
|
|
6
8
|
StageCrewMember,
|
|
7
9
|
StageCrewMemberBuilder
|
|
8
10
|
} from '@serenity-js/core';
|
|
9
|
-
import type { Actor } from '@serenity-js/core';
|
|
10
11
|
import type { ExtraBrowserContextOptions } from '@serenity-js/playwright';
|
|
12
|
+
import type { AxiosRequestConfigDefaults } from '@serenity-js/rest';
|
|
13
|
+
import { type AxiosInstance } from 'axios';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Serenity/JS-specific [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures)
|
|
@@ -241,31 +244,92 @@ export interface SerenityFixtures {
|
|
|
241
244
|
*/
|
|
242
245
|
extraContextOptions: Partial<ExtraBrowserContextOptions>;
|
|
243
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Extra abilities given to the actors on top of the default ones provided by the [`actors`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actors) fixture.
|
|
249
|
+
*
|
|
250
|
+
* #### Extra abilities for all actors
|
|
251
|
+
*
|
|
252
|
+
* To give the same set of extra abilities to all the actors, make your `extraAbilities` fixture
|
|
253
|
+
* return an array of [`Ability`](https://serenity-js.org/api/core/class/Ability/) objects.
|
|
254
|
+
*
|
|
255
|
+
* ```typescript
|
|
256
|
+
* import { type Ability } from '@serenity-js/core';
|
|
257
|
+
* import { describe, it, test } from '@serenity-js/playwright-test';
|
|
258
|
+
* import { MyAbility } from './MyAbility';
|
|
259
|
+
*
|
|
260
|
+
* describe(`My feature`, () => {
|
|
261
|
+
*
|
|
262
|
+
* test.use({
|
|
263
|
+
* extraAbilities: [ new MyAbility() ]
|
|
264
|
+
* });
|
|
265
|
+
*
|
|
266
|
+
* it(`...`, async({ actor }) => {
|
|
267
|
+
* // ...
|
|
268
|
+
* });
|
|
269
|
+
* });
|
|
270
|
+
* ```
|
|
271
|
+
*
|
|
272
|
+
* #### Extra abilities for selected actors
|
|
273
|
+
*
|
|
274
|
+
* To give extra abilities only to selected actors, make your `extraAbilities` fixture return a `(actorName: string) => Ability[]` function that maps
|
|
275
|
+
* the actor name to an array of [`Ability`](https://serenity-js.org/api/core/class/Ability/) objects.
|
|
276
|
+
*
|
|
277
|
+
* ```typescript
|
|
278
|
+
* import { describe, it, test } from '@serenity-js/playwright-test';
|
|
279
|
+
* import { MyAbility } from './MyAbility';
|
|
280
|
+
*
|
|
281
|
+
* describe(`My feature`, () => {
|
|
282
|
+
*
|
|
283
|
+
* test.use({
|
|
284
|
+
* extraAbilities: async ({ }, use) => {
|
|
285
|
+
* await use((actorName: string) => {
|
|
286
|
+
* // Alice gets the extra abilities, but others don't
|
|
287
|
+
* return actorName === 'Alice'
|
|
288
|
+
* ? [ new MyAbility() ]
|
|
289
|
+
* : [];
|
|
290
|
+
* })
|
|
291
|
+
* }
|
|
292
|
+
* });
|
|
293
|
+
*
|
|
294
|
+
* it(`...`, async({ actor }) => {
|
|
295
|
+
* // ...
|
|
296
|
+
* });
|
|
297
|
+
* });
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
extraAbilities: ((actorName: string) => Ability[]) | Ability[];
|
|
301
|
+
|
|
244
302
|
/**
|
|
245
303
|
* A cast of Serenity/JS actors to be used instead of the default cast
|
|
246
304
|
* when instantiating [`actor`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actor)
|
|
247
305
|
* and invoking [`actorCalled`](https://serenity-js.org/api/playwright-test/interface/SerenityWorkerFixtures/#actorCalled).
|
|
248
306
|
*
|
|
249
307
|
* :::info Did you know?
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* [
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
* :::
|
|
308
|
+
* Serenity/JS [test APIs](https://serenity-js.org/api/playwright-test/function/it/) offer fixtures that set up the default cast of actors for you,
|
|
309
|
+
* which should be sufficient in most web and HTTP API testing scenarios.
|
|
310
|
+
*
|
|
311
|
+
* Each one of the default actors receives the following [abilities](https://serenity-js.org/api/core/class/Ability/):
|
|
312
|
+
* - [`BrowseTheWebWithPlaywright`](https://serenity-js.org/api/playwright/class/BrowseTheWebWithPlaywright/), connected to Playwright [`page`](https://playwright.dev/docs/test-fixtures) fixture
|
|
313
|
+
* - [`TakeNotes`](https://serenity-js.org/api/core/class/TakeNotes/#usingAnEmptyNotepad)
|
|
314
|
+
* - [`CallAnApi`](https://serenity-js.org/api/rest/class/CallAnApi/), pointing at the [`baseURL`](https://playwright.dev/docs/test-use-options#basic-options)
|
|
315
|
+
* and using any `proxy` settings in your Playwright config file.
|
|
259
316
|
*
|
|
317
|
+
* The easiest way to give your actors additional abilities is to use the [`extraAbilities`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#extraAbilities) fixture.
|
|
318
|
+
* :::
|
|
260
319
|
*
|
|
261
320
|
* #### Overriding the default cast of Serenity/JS actors
|
|
262
321
|
*
|
|
263
322
|
* ```typescript
|
|
264
|
-
* import { Cast, TakeNotes } from '@serenity-js/core'
|
|
265
323
|
* import { Ensure, equals } from '@serenity-js/assertions'
|
|
324
|
+
* import { Cast, TakeNotes } from '@serenity-js/core'
|
|
266
325
|
* import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright'
|
|
326
|
+
* import { CallAnApi } from '@serenity-js/rest'
|
|
267
327
|
* import { describe, it, test } from '@serenity-js/playwright-test'
|
|
268
328
|
*
|
|
329
|
+
* interface MyNotes {
|
|
330
|
+
* username: string;
|
|
331
|
+
* }
|
|
332
|
+
*
|
|
269
333
|
* describe(`Recording items`, () => {
|
|
270
334
|
*
|
|
271
335
|
* test.use({
|
|
@@ -273,17 +337,24 @@ export interface SerenityFixtures {
|
|
|
273
337
|
* defaultNavigationTimeout: 30_000,
|
|
274
338
|
* },
|
|
275
339
|
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
340
|
+
* actors: async ({ axios, extraAbilities, extraContextOptions, extraHTTPHeaders, page }, use) => {
|
|
341
|
+
* const cast = Cast.where(actor => {
|
|
342
|
+
* const abilities = Array.isArray(extraAbilities)
|
|
343
|
+
* ? extraAbilities
|
|
344
|
+
* : extraAbilities(actor.name);
|
|
345
|
+
*
|
|
346
|
+
* return actor.whoCan(
|
|
347
|
+
* BrowseTheWebWithPlaywright.usingPage(page, extraContextOptions),
|
|
348
|
+
* TakeNotes.using<MyNotes>(Notepad.with({
|
|
349
|
+
* username: 'example.username'
|
|
350
|
+
* }),
|
|
351
|
+
* CallAnApi.using(axios),
|
|
352
|
+
* ...abilities,
|
|
282
353
|
* )
|
|
283
|
-
* )
|
|
354
|
+
* })
|
|
284
355
|
*
|
|
285
356
|
* // Make sure to pass your custom cast to Playwright `use` callback
|
|
286
|
-
* await use(cast)
|
|
357
|
+
* await use(cast);
|
|
287
358
|
* },
|
|
288
359
|
* })
|
|
289
360
|
*
|
|
@@ -302,7 +373,7 @@ export interface SerenityFixtures {
|
|
|
302
373
|
* })
|
|
303
374
|
* })
|
|
304
375
|
* })
|
|
305
|
-
*
|
|
376
|
+
* ```
|
|
306
377
|
*
|
|
307
378
|
* #### Learn more
|
|
308
379
|
* - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/)
|
|
@@ -322,6 +393,18 @@ export interface SerenityFixtures {
|
|
|
322
393
|
* - Declaring a Serenity/JS [test scenario](https://serenity-js.org/api/playwright-test/function/it/)
|
|
323
394
|
*/
|
|
324
395
|
actor: Actor;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* An instance of the Axios HTTP client, or default Axios request configurations,
|
|
399
|
+
* to be used by the [`CallAnApi`](https://serenity-js.org/api/rest/class/CallAnApi/) ability,
|
|
400
|
+
* provided to the actors via the [`actors`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actors) fixture.
|
|
401
|
+
*
|
|
402
|
+
* By default, Serenity/JS configures Axios to use the following settings from your Playwright configuration file:
|
|
403
|
+
* - [`baseURL`](https://playwright.dev/docs/api/class-testoptions#test-options-base-url)
|
|
404
|
+
* - [`proxy`](https://playwright.dev/docs/api/class-testoptions#test-options-proxy)
|
|
405
|
+
* - [`extraHTTPHeaders`](https://playwright.dev/docs/api/class-testoptions#test-options-extra-http-headers)
|
|
406
|
+
*/
|
|
407
|
+
axios: AxiosInstance | AxiosRequestConfigDefaults;
|
|
325
408
|
}
|
|
326
409
|
|
|
327
410
|
/**
|
|
@@ -370,7 +453,9 @@ export interface SerenityWorkerFixtures {
|
|
|
370
453
|
serenity: Serenity;
|
|
371
454
|
|
|
372
455
|
/**
|
|
373
|
-
* Uses the provided [cast](https://serenity-js.org/api/core/class/Cast/) of
|
|
456
|
+
* Uses the provided [cast](https://serenity-js.org/api/core/class/Cast/) of
|
|
457
|
+
* [`actors`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/#actors) to instantiate
|
|
458
|
+
* an [`Actor`](https://serenity-js.org/api/core/class/Actor/) called `name`
|
|
374
459
|
* and inject it into a [test scenario](https://serenity-js.org/api/playwright-test/function/it/).
|
|
375
460
|
*
|
|
376
461
|
* Retrieves an existing actor if one has already been instantiated.
|
package/src/api/test-api.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
TestType,
|
|
14
14
|
WorkerInfo,
|
|
15
15
|
} from '@playwright/test';
|
|
16
|
-
import { test as playwrightBaseTest } from '@playwright/test';
|
|
16
|
+
import { mergeTests, test as playwrightBaseTest } from '@playwright/test';
|
|
17
17
|
import type { DiffFormatter } from '@serenity-js/core';
|
|
18
18
|
import { AnsiDiffFormatter, Cast, Clock, Duration, Serenity, TakeNotes } from '@serenity-js/core';
|
|
19
19
|
import { SceneFinishes, SceneTagged } from '@serenity-js/core/lib/events';
|
|
@@ -68,20 +68,32 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
68
68
|
{ option: true },
|
|
69
69
|
],
|
|
70
70
|
|
|
71
|
+
axios: async ({ baseURL, extraHTTPHeaders, proxy }, use) => {
|
|
72
|
+
await use({
|
|
73
|
+
baseURL: baseURL,
|
|
74
|
+
headers: extraHTTPHeaders,
|
|
75
|
+
proxy: proxy && proxy?.server
|
|
76
|
+
? asProxyConfig(proxy)
|
|
77
|
+
: undefined,
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
|
|
71
81
|
actors: [
|
|
72
82
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
73
|
-
async ({
|
|
74
|
-
await use(Cast.where(actor =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
async ({ axios, extraAbilities, extraContextOptions, page }, use): Promise<void> => {
|
|
84
|
+
await use(Cast.where(actor => {
|
|
85
|
+
|
|
86
|
+
const abilities = Array.isArray(extraAbilities)
|
|
87
|
+
? extraAbilities
|
|
88
|
+
: extraAbilities(actor.name);
|
|
89
|
+
|
|
90
|
+
return actor.whoCan(
|
|
91
|
+
BrowseTheWebWithPlaywright.usingPage(page, extraContextOptions),
|
|
92
|
+
TakeNotes.usingAnEmptyNotepad(),
|
|
93
|
+
CallAnApi.using(axios),
|
|
94
|
+
...abilities,
|
|
95
|
+
);
|
|
96
|
+
}));
|
|
85
97
|
},
|
|
86
98
|
{ option: true },
|
|
87
99
|
],
|
|
@@ -109,7 +121,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
109
121
|
|
|
110
122
|
sceneIdFactoryInternal: [
|
|
111
123
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,no-empty-pattern
|
|
112
|
-
async ({
|
|
124
|
+
async ({}, use) => {
|
|
113
125
|
await use(new PlaywrightTestSceneIdFactory());
|
|
114
126
|
},
|
|
115
127
|
{ scope: 'worker', box: true },
|
|
@@ -132,7 +144,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
132
144
|
|
|
133
145
|
eventStreamWriterInternal: [
|
|
134
146
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,no-empty-pattern
|
|
135
|
-
async ({
|
|
147
|
+
async ({}, use, workerInfo) => {
|
|
136
148
|
|
|
137
149
|
const serenityOutputDirectory = path.join(workerInfo.project.outputDir, 'serenity');
|
|
138
150
|
|
|
@@ -225,12 +237,18 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
225
237
|
{ auto: true, box: true, }
|
|
226
238
|
],
|
|
227
239
|
|
|
240
|
+
extraAbilities: [
|
|
241
|
+
[],
|
|
242
|
+
{ option: true },
|
|
243
|
+
],
|
|
244
|
+
|
|
228
245
|
actorCalled: [
|
|
229
246
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
230
247
|
async ({ serenity }, use) => {
|
|
231
248
|
|
|
232
249
|
const actorCalled = (name: string) => {
|
|
233
250
|
const actor = serenity.theActorCalled(name);
|
|
251
|
+
|
|
234
252
|
return actor.whoCan(new PerformActivitiesAsPlaywrightSteps(actor, serenity, it));
|
|
235
253
|
};
|
|
236
254
|
|
|
@@ -247,7 +265,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
247
265
|
/**
|
|
248
266
|
* Serenity/JS BDD-style test API created by [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/).
|
|
249
267
|
*/
|
|
250
|
-
export type TestApi<TestArgs extends
|
|
268
|
+
export type TestApi<TestArgs extends object, WorkerArgs extends object> =
|
|
251
269
|
Pick<TestType<TestArgs, WorkerArgs>, 'describe' | 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll' | 'expect'> &
|
|
252
270
|
{
|
|
253
271
|
/**
|
|
@@ -274,7 +292,7 @@ export type TestApi<TestArgs extends Record<string, any>, WorkerArgs extends Rec
|
|
|
274
292
|
*
|
|
275
293
|
* Shorthand for [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/)
|
|
276
294
|
*/
|
|
277
|
-
useFixtures: <T extends
|
|
295
|
+
useFixtures: <T extends object, W extends object = object>(
|
|
278
296
|
customFixtures: Fixtures<T, W, TestArgs, WorkerArgs>
|
|
279
297
|
) => TestApi<TestArgs & T, WorkerArgs & W>,
|
|
280
298
|
|
|
@@ -282,7 +300,7 @@ export type TestApi<TestArgs extends Record<string, any>, WorkerArgs extends Rec
|
|
|
282
300
|
test: TestType<TestArgs, WorkerArgs>,
|
|
283
301
|
}
|
|
284
302
|
|
|
285
|
-
function createTestApi<BaseTestFixtures extends
|
|
303
|
+
function createTestApi<BaseTestFixtures extends object, BaseWorkerFixtures extends object>(baseTest: TestType<BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures, BaseWorkerFixtures> {
|
|
286
304
|
return {
|
|
287
305
|
useFixtures<T extends Record<string, any>, W extends Record<string, any> = object>(customFixtures: Fixtures<T, W, BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures & T, BaseWorkerFixtures & W> {
|
|
288
306
|
return createTestApi(baseTest.extend(customFixtures));
|
|
@@ -426,6 +444,9 @@ export const expect: Expect = api.expect;
|
|
|
426
444
|
|
|
427
445
|
export const useFixtures = api.useFixtures;
|
|
428
446
|
|
|
447
|
+
type MergedT<List> = List extends [ TestType<infer T, any>, ...(infer Rest) ] ? T & MergedT<Rest> : object;
|
|
448
|
+
type MergedW<List> = List extends [ TestType<any, infer W>, ...(infer Rest) ] ? W & MergedW<Rest> : object;
|
|
449
|
+
|
|
429
450
|
/**
|
|
430
451
|
* Creates a Serenity/JS BDD-style test API around the given Playwright [base test](https://playwright.dev/docs/test-fixtures).
|
|
431
452
|
*
|
|
@@ -562,15 +583,45 @@ export const useFixtures = api.useFixtures;
|
|
|
562
583
|
* })
|
|
563
584
|
* ```
|
|
564
585
|
*
|
|
565
|
-
*
|
|
586
|
+
* ## Merging multiple base tests
|
|
587
|
+
*
|
|
588
|
+
* To merge fixtures from multiple files or modules, pass them to `useBase`.
|
|
589
|
+
*
|
|
590
|
+
* ```tsx
|
|
591
|
+
* import { test as componentTest } from '@playwright/experimental-ct-react'
|
|
592
|
+
* import { test as a11yTest } from 'my-a11y-test-utils';
|
|
593
|
+
* import { Ensure, contain } from '@serenity-js/assertions'
|
|
594
|
+
* import { useBase } from '@serenity-js/playwright-test'
|
|
595
|
+
* import { Enter, PageElement, CssClasses } from '@serenity-js/web'
|
|
596
|
+
*
|
|
597
|
+
* import EmailInput from './EmailInput';
|
|
598
|
+
*
|
|
599
|
+
* const { it, describe } = useBase(componentTest, a11yTest).useFixtures<{ emailAddress: string }>({
|
|
600
|
+
* emailAddress: ({ actor }, use) => {
|
|
601
|
+
* use(`${ actor.name }@example.org`)
|
|
602
|
+
* }
|
|
603
|
+
* })
|
|
604
|
+
*
|
|
605
|
+
* describe('EmailInput', () => {
|
|
606
|
+
*
|
|
607
|
+
* it('allows valid email addresses', async ({ actor, mount, emailAddress }) => {
|
|
608
|
+
* const nativeComponent = await mount(<EmailInput/>);
|
|
609
|
+
*
|
|
610
|
+
* const component = PageElement.from(nativeComponent);
|
|
611
|
+
*
|
|
612
|
+
* await actor.attemptsTo(
|
|
613
|
+
* Enter.theValue(emailAddress).into(component),
|
|
614
|
+
* Ensure.that(CssClasses.of(component), contain('valid')),
|
|
615
|
+
* )
|
|
616
|
+
* })
|
|
617
|
+
* })
|
|
618
|
+
* ```
|
|
619
|
+
*
|
|
620
|
+
* @param baseTests
|
|
566
621
|
*/
|
|
567
|
-
export function useBase<
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
> (baseTest: TestType<BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures & SerenityFixtures, BaseWorkerFixtures & SerenityWorkerFixtures> {
|
|
571
|
-
return createTestApi<BaseTestFixtures, BaseWorkerFixtures>(baseTest).useFixtures(
|
|
572
|
-
fixtures as Fixtures<SerenityFixtures, SerenityWorkerFixtures, BaseTestFixtures, BaseWorkerFixtures>
|
|
573
|
-
);
|
|
622
|
+
export function useBase<List extends any[]>(...baseTests: List): TestApi<MergedT<List> & SerenityFixtures, MergedW<List> & SerenityWorkerFixtures> {
|
|
623
|
+
return createTestApi<MergedT<List>, MergedW<List>>(mergeTests(...baseTests))
|
|
624
|
+
.useFixtures(fixtures as Fixtures<SerenityFixtures, SerenityWorkerFixtures, MergedT<List>, MergedW<List>>);
|
|
574
625
|
}
|
|
575
626
|
|
|
576
627
|
/**
|
|
@@ -602,13 +653,14 @@ function asProxyConfig(proxy: PlaywrightTestOptions['proxy']): {
|
|
|
602
653
|
auth?: { username: string, password: string }
|
|
603
654
|
bypass?: string;
|
|
604
655
|
} {
|
|
656
|
+
const proxyServer = proxy.server.trim();
|
|
605
657
|
|
|
606
658
|
// Playwright defaults to http when proxy.server does not define the protocol
|
|
607
659
|
// See https://playwright.dev/docs/api/class-testoptions#test-options-proxy
|
|
608
|
-
const hasProtocol =
|
|
660
|
+
const hasProtocol = /^[\dA-Za-z]+:\/\//.test(proxyServer);
|
|
609
661
|
const proxyUrl = hasProtocol
|
|
610
|
-
? new URL(
|
|
611
|
-
: new URL(`http://${
|
|
662
|
+
? new URL(proxyServer)
|
|
663
|
+
: new URL(`http://${ proxyServer }`);
|
|
612
664
|
|
|
613
665
|
const host = proxyUrl.hostname;
|
|
614
666
|
const port = proxyUrl.port
|