Skip to content

Commit 75acde2

Browse files
committed
E2E: leave no navigation in flight when authenticate() returns
Calypso home hands a logged-in user over to the Dashboard on another host, and that navigation starts after the load event. A spec that authenticates with waitUntilStable false and navigates straight away raced it and lost: reader__view failed both its attempts on both devices with ERR_ABORTED on the goto to /reader, with the Dashboard shell on screen. The prime-logins project hid this. It logged in as the account before the suite, so by the time the spec ran the container had served the same pages already and the hand-over fired earlier than the spec's own navigation. Such a caller navigates itself next, so authenticate() no longer loads Calypso home for it, and it waits for the URL to stop changing before it returns.
1 parent d67bd60 commit 75acde2

1 file changed

Lines changed: 34 additions & 1 deletion

File tree

packages/calypso-e2e/src/lib/test-account.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const LOCK_STALE_MS = 90 * 1000;
2121
const LOCK_WAIT_MS = 60 * 1000;
2222
const LOCK_POLL_MS = 500;
2323
const LOGIN_ATTEMPTS = 2;
24+
const SETTLE_POLL_MS = 500;
25+
const SETTLE_TIMEOUT_MS = 10 * 1000;
2426

2527
/**
2628
* Creates a directory, reporting whether this call is the one that created it.
@@ -39,6 +41,30 @@ async function createdDirectory( dirPath: string ): Promise< boolean > {
3941
}
4042
}
4143

44+
/**
45+
* Waits until the page stops navigating on its own.
46+
*
47+
* Calypso home hands a logged-in user over to the Dashboard, which lives on another host, and
48+
* that navigation starts after the load event. Handing back a page with it still in flight
49+
* aborts whatever the caller navigates to next.
50+
*
51+
* @param {Page} page Page to watch.
52+
*/
53+
async function waitForNavigationToSettle( page: Page ): Promise< void > {
54+
// Polls the URL rather than waiting for a named destination: where a logged-in user lands
55+
// is the app's business and has changed before.
56+
const deadline = Date.now() + SETTLE_TIMEOUT_MS;
57+
let url = page.url();
58+
59+
while ( Date.now() < deadline ) {
60+
await sleep( SETTLE_POLL_MS );
61+
if ( page.url() === url ) {
62+
return;
63+
}
64+
url = page.url();
65+
}
66+
}
67+
4268
/**
4369
* Represents the WPCOM test account.
4470
*/
@@ -79,11 +105,16 @@ export class TestAccount {
79105
{ url, waitUntilStable = true }: { url?: string | RegExp; waitUntilStable?: boolean } = {}
80106
): Promise< void > {
81107
const browserContext = page.context();
108+
// A caller that asks for neither a URL nor stability navigates itself next, so landing
109+
// on Calypso home first only buys a redirect that competes with that navigation.
110+
const landOnCalypsoHome = Boolean( url ) || waitUntilStable;
82111

83112
if ( ! ( await this.logInOncePerRun( page ) ) ) {
84113
await browserContext.clearCookies();
85114
await browserContext.addCookies( await this.getAuthCookies() );
86-
await page.goto( getCalypsoURL( '/' ) );
115+
if ( landOnCalypsoHome ) {
116+
await page.goto( getCalypsoURL( '/' ) );
117+
}
87118
}
88119

89120
if ( url ) {
@@ -92,6 +123,8 @@ export class TestAccount {
92123
if ( waitUntilStable ) {
93124
const sidebarComponent = new SidebarComponent( page );
94125
await sidebarComponent.waitForSidebarInitialization();
126+
} else {
127+
await waitForNavigationToSettle( page );
95128
}
96129
}
97130

0 commit comments

Comments
 (0)