Skip to content

Commit 477b1c4

Browse files
committed
PRO-10170 fix: add switchPlaywrightPage internal switcher
1 parent f015362 commit 477b1c4

15 files changed

Lines changed: 195 additions & 52 deletions

File tree

autotests/pageObjects/pages/E2edReportExample/E2edReportExample.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
} from 'autotests/actions';
55
import {setPageCookies, setPageRequestHeaders} from 'autotests/context';
66
import {E2edReportExample as E2edReportExampleRoute} from 'autotests/routes/pageRoutes';
7-
import {createSelector, locator} from 'autotests/selectors';
7+
import {locator} from 'autotests/selectors';
88
import {Page} from 'e2ed';
99
import {setReadonlyProperty} from 'e2ed/utils';
1010

@@ -23,7 +23,7 @@ export class E2edReportExample extends Page<CustomPageParams> {
2323
/**
2424
* Page header.
2525
*/
26-
readonly header: Selector = createSelector('.header');
26+
readonly header: Selector = locator('header');
2727

2828
/**
2929
* Navigation bar with test retries.

autotests/tests/switchingPages.ts

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,64 @@
1+
/* eslint-disable @typescript-eslint/no-magic-numbers */
2+
13
import {test} from 'autotests';
24
import {getUsers} from 'autotests/entities';
35
import {E2edReportExample} from 'autotests/pageObjects/pages';
46
import {GetUsers} from 'autotests/routes/apiRoutes';
57
import {expect} from 'e2ed';
6-
import {navigateToPage, waitForRequestToRoute, waitForTimeout} from 'e2ed/actions';
8+
import {
9+
click,
10+
navigateToPage,
11+
switchToTab,
12+
waitForNewTab,
13+
waitForRequestToRoute,
14+
waitForTimeout,
15+
} from 'e2ed/actions';
716
import {log} from 'e2ed/utils';
817

9-
const maxNumberOfRequests = 10;
18+
const maxNumberOfRequests = 15;
19+
20+
const timeout = (maxNumberOfRequests + 5) * 1_000;
21+
22+
test(
23+
'support switching of pages and tabs',
24+
{meta: {testId: '21'}, testTimeout: timeout + 1_000},
25+
async () => {
26+
let numberOfCaughtRequests = 0;
27+
let numberOfSentRequests = 0;
28+
29+
setInterval(() => {
30+
if (numberOfSentRequests < maxNumberOfRequests) {
31+
numberOfSentRequests += 1;
1032

11-
const timeout = (maxNumberOfRequests + 2) * 1_000;
33+
void getUsers({retries: 1});
34+
}
35+
}, 1_000);
1236

13-
test('support switching of pages and tabs', {meta: {testId: '21'}}, async () => {
14-
let numberOfCaughtRequests = 0;
15-
let numberOfSentRequests = 0;
37+
void waitForRequestToRoute(GetUsers, {
38+
predicate: (routeParams, request) => {
39+
numberOfCaughtRequests += 1;
1640

17-
setInterval(() => {
18-
if (numberOfSentRequests < maxNumberOfRequests) {
19-
numberOfSentRequests += 1;
41+
log(`Caught request number ${numberOfCaughtRequests}`, {request, routeParams});
2042

21-
void getUsers({retries: 1});
22-
}
23-
}, 1_000);
43+
return false;
44+
},
45+
timeout,
46+
});
2447

25-
void waitForRequestToRoute(GetUsers, {
26-
predicate: (routeParams, request) => {
27-
numberOfCaughtRequests += 1;
48+
await waitForTimeout(maxNumberOfRequests * 333);
2849

29-
log(`Caught request number ${numberOfCaughtRequests}`, {routeParams, request});
50+
const reportPage = await navigateToPage(E2edReportExample);
3051

31-
return false;
32-
},
33-
timeout,
34-
});
52+
await waitForTimeout(maxNumberOfRequests * 333);
3553

36-
await waitForTimeout(maxNumberOfRequests * 500);
54+
const npmPageTab = await waitForNewTab(async () => {
55+
await click(reportPage.header);
56+
});
3757

38-
await navigateToPage(E2edReportExample);
58+
switchToTab(npmPageTab);
3959

40-
await waitForTimeout(maxNumberOfRequests * 500 + 1_000);
60+
await waitForTimeout(maxNumberOfRequests * 333 + 1_000);
4161

42-
await expect(numberOfSentRequests, 'all requests were caught').eql(numberOfCaughtRequests);
43-
});
62+
await expect(numberOfSentRequests, 'all requests were caught').eql(numberOfCaughtRequests);
63+
},
64+
);

src/actions/switchToMainTab.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ import {LogEventType} from '../constants/internal';
22
import {clearTab} from '../context/tab';
33
import {getPlaywrightPage} from '../useContext';
44
import {log} from '../utils/log';
5+
import {switchPlaywrightPage} from '../utils/playwrightPage';
56

67
/**
78
* Switches page context to the specified tab.
89
*/
910
export const switchToMainTab = (): void => {
11+
clearTab();
12+
1013
const page = getPlaywrightPage();
1114
const url = page.url();
1215

1316
log(`Switch page context to the main tab at ${url}`, LogEventType.InternalAction);
1417

15-
clearTab();
18+
switchPlaywrightPage(page);
1619
};

src/actions/switchToTab.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {LogEventType} from '../constants/internal';
22
import {setTab} from '../context/tab';
33
import {log} from '../utils/log';
4+
import {switchPlaywrightPage} from '../utils/playwrightPage';
45

56
import type {InternalTab, Tab} from '../types/internal';
67

@@ -14,4 +15,6 @@ export const switchToTab = (tab: Tab): void => {
1415
log(`Switch page context to the specified tab at ${url}`, LogEventType.InternalAction);
1516

1617
setTab(tab);
18+
19+
switchPlaywrightPage(page);
1720
};

src/actions/waitFor/waitForRequest.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {E2edError} from '../../utils/error';
88
import {setCustomInspectOnFunction} from '../../utils/fn';
99
import {getDurationWithUnits} from '../../utils/getDurationWithUnits';
1010
import {log} from '../../utils/log';
11+
import {pageWaitForRequest} from '../../utils/playwrightPage';
1112
import {addTimeoutToPromise} from '../../utils/promise';
1213
import {getRequestFromPlaywrightRequest} from '../../utils/requestHooks';
1314

@@ -68,7 +69,8 @@ export const waitForRequest = (async <SomeRequest extends Request>(
6869
const timeoutWithUnits = getDurationWithUnits(timeout);
6970

7071
const promise = addTimeoutToPromise(
71-
page.waitForRequest(
72+
pageWaitForRequest(
73+
page,
7274
AsyncLocalStorage.bind(async (playwrightRequest: PlaywrightRequest) => {
7375
try {
7476
const request = getRequestFromPlaywrightRequest(playwrightRequest);

src/types/report.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export type ReportClientData = Readonly<{
9393
export type ReportClientState = {
9494
clickListeners?: Record<string, (event: HTMLElement) => void>;
9595
readonly createLocatorOptions: CreateLocatorOptions;
96-
readonly e2edRightColumnContainer: HTMLElement;
96+
readonly e2edRightColumnContainer: HTMLElement | undefined;
9797
readonly fullTestRuns: readonly FullTestRun[];
9898
readonly internalDirectoryName: string;
9999
lengthOfReadedJsonReportDataParts: number;

src/utils/generalLog/logFile.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,11 @@ import {getFullPackConfig} from '../config';
1111
*/
1212
const logs: string[] = [];
1313

14-
/**
15-
* Adds log message to pack logs (for later saving to the pack logs file).
16-
* @internal
17-
*/
18-
export const addLogToLogFile = (logMessage: string): void => {
19-
logs.push(logMessage);
20-
};
21-
2214
/**
2315
* Writes pack logs to logs file (if the pack config requires it and there are unwritten logs).
2416
* @internal
2517
*/
26-
export const writeLogsToFile = async (): Promise<void> => {
18+
const writeLogsToFile = async (): Promise<void> => {
2719
if (logs.length === 0) {
2820
return;
2921
}
@@ -41,3 +33,24 @@ export const writeLogsToFile = async (): Promise<void> => {
4133

4234
await appendFile(logsFilePath, logsText);
4335
};
36+
37+
const baseWritingInternal = 4_000;
38+
const deltaWritingInterval = 4_000;
39+
40+
setInterval(
41+
() => {
42+
void writeLogsToFile();
43+
},
44+
baseWritingInternal + Math.random() * deltaWritingInterval,
45+
);
46+
47+
/**
48+
* Adds log message to pack logs (for later saving to the pack logs file).
49+
* @internal
50+
*/
51+
export const addLogToLogFile = (logMessage: string): void => {
52+
logs.push(logMessage);
53+
};
54+
55+
/** @internal */
56+
export {writeLogsToFile};

src/utils/getGlobalErrorHandler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {E2edError} from './error';
22
import {writeGlobalError} from './fs';
3+
import {writeLogsToFile} from './generalLog';
34

45
import type {GlobalErrorType} from '../types/internal';
56

@@ -12,5 +13,6 @@ export const getGlobalErrorHandler =
1213
(cause: unknown): void => {
1314
const error = new E2edError(`Caught ${type}`, {cause});
1415

15-
void writeGlobalError(error.toString());
16+
void writeGlobalError(error.toString()).catch(() => {});
17+
void writeLogsToFile().catch(() => {});
1618
};

src/utils/playwrightPage/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** @internal */
2+
export {switchPlaywrightPage} from './switchPlaywrightPage';
3+
/** @internal */
4+
export {pageWaitForRequest} from './waitForRequest';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {pageWaitForRequest, waitForRequestCalls} from './waitForRequest';
2+
3+
import type {Page} from '@playwright/test';
4+
5+
/**
6+
* Switches internal Playwright page from old to new.
7+
* Removes all event handlers from the old page and moves them to the new one.
8+
* @internal
9+
*/
10+
export const switchPlaywrightPage = (newPage: Page): void => {
11+
const oldCalls = [...waitForRequestCalls];
12+
13+
waitForRequestCalls.length = 0;
14+
15+
for (const {disablePredicate, options, predicate, reject, resolve} of oldCalls) {
16+
disablePredicate();
17+
18+
pageWaitForRequest(newPage, predicate, options).then(resolve, reject);
19+
}
20+
};

0 commit comments

Comments
 (0)