@@ -19,82 +19,107 @@ import { stripAnsi } from 'tests/config/utils';
19
19
import type { TestServer } from '../config/testserver' ;
20
20
import { test as it , expect } from './pageTest' ;
21
21
22
- function initServer ( server : TestServer ) : string [ ] {
22
+ function initStallingServer ( server : TestServer , url ?: string ) {
23
+ let release : ( ) => void ;
24
+ const releasePromise = new Promise < void > ( r => release = r ) ;
25
+ let route : ( ) => void ;
26
+ const routePromise = new Promise < void > ( r => route = r ) ;
23
27
const messages = [ ] ;
24
- server . setRoute ( '/empty.html' , async ( req , res ) => {
28
+ server . setRoute ( url ?? '/empty.html' , async ( req , res ) => {
25
29
messages . push ( 'route' ) ;
30
+ route ( ) ;
31
+ await releasePromise ;
26
32
res . setHeader ( 'Content-Type' , 'text/html' ) ;
27
- res . end ( `<link rel='stylesheet' href='./one-style.css' >` ) ;
33
+ res . end ( `<button onclick="window.__clicked=true">click me</button >` ) ;
28
34
} ) ;
29
- return messages ;
35
+ return { messages, release , routed : routePromise } ;
30
36
}
31
37
32
- it ( 'should await navigation when clicking anchor' , async ( { page, server } ) => {
33
- const messages = initServer ( server ) ;
34
- await page . setContent ( `<a id="anchor" href="${ server . EMPTY_PAGE } ">empty.html</a>` ) ;
35
- await Promise . all ( [
36
- page . click ( 'a' ) . then ( ( ) => messages . push ( 'click' ) ) ,
37
- page . waitForEvent ( 'framenavigated' ) . then ( ( ) => messages . push ( 'navigated' ) ) ,
38
- ] ) ;
39
- expect ( messages . join ( '|' ) ) . toBe ( 'route|navigated|click' ) ;
38
+ it ( 'should await navigation before clicking anchor' , async ( { page, server } ) => {
39
+ const { messages, release, routed } = initStallingServer ( server ) ;
40
+ await page . setContent ( `<a href="${ server . EMPTY_PAGE } ">empty.html</a>` ) ;
41
+
42
+ await page . click ( 'a' ) ;
43
+ await routed ;
44
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
45
+
46
+ const click2 = page . click ( 'button' ) . then ( ( ) => messages . push ( 'click2' ) ) ;
47
+ await page . waitForTimeout ( 1000 ) ;
48
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
49
+
50
+ release ( ) ;
51
+ await click2 ;
52
+ expect ( messages . join ( '|' ) ) . toBe ( 'route|click2' ) ;
40
53
} ) ;
41
54
42
55
it ( 'should not stall on JS navigation link' , async ( { page, browserName } ) => {
43
56
await page . setContent ( `<a href="javascript:console.log(1)">console.log</a>` ) ;
44
57
await page . click ( 'a' ) ;
45
58
} ) ;
46
59
47
- it ( 'should await cross-process navigation when clicking anchor' , async ( { page, server } ) => {
48
- const messages = initServer ( server ) ;
60
+ it ( 'should await cross-process navigation before clicking anchor' , async ( { page, server } ) => {
61
+ const { messages, release , routed } = initStallingServer ( server ) ;
49
62
await page . setContent ( `<a href="${ server . CROSS_PROCESS_PREFIX + '/empty.html' } ">empty.html</a>` ) ;
50
63
51
- await Promise . all ( [
52
- page . click ( 'a' ) . then ( ( ) => messages . push ( 'click' ) ) ,
53
- page . waitForEvent ( 'framenavigated' ) . then ( ( ) => messages . push ( 'navigated' ) ) ,
54
- ] ) ;
55
- expect ( messages . join ( '|' ) ) . toBe ( 'route|navigated|click' ) ;
56
- } ) ;
64
+ await page . click ( 'a' ) ;
65
+ await routed ;
66
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
57
67
58
- it ( 'should await form-get on click' , async ( { page, server } ) => {
59
- const messages = [ ] ;
60
- server . setRoute ( '/empty.html?foo=bar' , async ( req , res ) => {
61
- messages . push ( 'route' ) ;
62
- res . setHeader ( 'Content-Type' , 'text/html' ) ;
63
- res . end ( `<link rel='stylesheet' href='./one-style.css'>` ) ;
64
- } ) ;
68
+ const click2 = page . click ( 'button' ) . then ( ( ) => messages . push ( 'click2' ) ) ;
69
+ await page . waitForTimeout ( 1000 ) ;
70
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
71
+
72
+ release ( ) ;
73
+ await click2 ;
74
+ expect ( messages . join ( '|' ) ) . toBe ( 'route|click2' ) ;
75
+ } ) ;
65
76
77
+ it ( 'should await form-get navigation before click' , async ( { page, server } ) => {
78
+ const { messages, release, routed } = initStallingServer ( server , '/empty.html?foo=bar' ) ;
66
79
await page . setContent ( `
67
80
<form action="${ server . EMPTY_PAGE } " method="get">
68
81
<input name="foo" value="bar">
69
82
<input type="submit" value="Submit">
70
83
</form>` ) ;
71
84
72
- await Promise . all ( [
73
- page . click ( 'input[type=submit]' ) . then ( ( ) => messages . push ( 'click' ) ) ,
74
- page . waitForEvent ( 'framenavigated' ) . then ( ( ) => messages . push ( 'navigated' ) ) ,
75
- ] ) ;
76
- expect ( messages . join ( '|' ) ) . toBe ( 'route|navigated|click' ) ;
85
+ await page . click ( 'input[type=submit]' ) ;
86
+ await routed ;
87
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
88
+
89
+ const click2 = page . click ( 'button' ) . then ( ( ) => messages . push ( 'click2' ) ) ;
90
+ await page . waitForTimeout ( 1000 ) ;
91
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
92
+
93
+ release ( ) ;
94
+ await click2 ;
95
+ expect ( messages . join ( '|' ) ) . toBe ( 'route|click2' ) ;
77
96
} ) ;
78
97
79
- it ( 'should await form-post on click' , async ( { page, server } ) => {
80
- const messages = initServer ( server ) ;
98
+ it ( 'should await form-post navigation before click' , async ( { page, server } ) => {
99
+ const { messages, release , routed } = initStallingServer ( server ) ;
81
100
await page . setContent ( `
82
101
<form action="${ server . EMPTY_PAGE } " method="post">
83
102
<input name="foo" value="bar">
84
103
<input type="submit" value="Submit">
85
104
</form>` ) ;
86
105
87
- await Promise . all ( [
88
- page . click ( 'input[type=submit]' ) . then ( ( ) => messages . push ( 'click' ) ) ,
89
- page . waitForEvent ( 'framenavigated' ) . then ( ( ) => messages . push ( 'navigated' ) ) ,
90
- ] ) ;
91
- expect ( messages . join ( '|' ) ) . toBe ( 'route|navigated|click' ) ;
106
+ await page . click ( 'input[type=submit]' ) ;
107
+ await routed ;
108
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
109
+
110
+ const click2 = page . click ( 'button' ) . then ( ( ) => messages . push ( 'click2' ) ) ;
111
+ await page . waitForTimeout ( 1000 ) ;
112
+ expect ( messages . join ( '|' ) ) . toBe ( 'route' ) ;
113
+
114
+ release ( ) ;
115
+ await click2 ;
116
+ expect ( messages . join ( '|' ) ) . toBe ( 'route|click2' ) ;
92
117
} ) ;
93
118
94
- it ( 'should work with noWaitAfter: true ' , async ( { page, server } ) => {
119
+ it ( 'should work without noWaitAfter when navigation is stalled ' , async ( { page, server } ) => {
95
120
server . setRoute ( '/empty.html' , async ( ) => { } ) ;
96
121
await page . setContent ( `<a id="anchor" href="${ server . EMPTY_PAGE } ">empty.html</a>` ) ;
97
- await page . click ( 'a' , { noWaitAfter : true } ) ;
122
+ await page . click ( 'a' ) ;
98
123
} ) ;
99
124
100
125
it ( 'should work with dblclick without noWaitAfter when navigation is stalled' , async ( { page, server } ) => {
@@ -103,16 +128,6 @@ it('should work with dblclick without noWaitAfter when navigation is stalled', a
103
128
await page . dblclick ( 'a' ) ;
104
129
} ) ;
105
130
106
- it ( 'should work with waitForLoadState(load)' , async ( { page, server } ) => {
107
- const messages = initServer ( server ) ;
108
- await page . setContent ( `<a id="anchor" href="${ server . EMPTY_PAGE } ">empty.html</a>` ) ;
109
- await Promise . all ( [
110
- page . click ( 'a' ) . then ( ( ) => page . waitForLoadState ( 'load' ) ) . then ( ( ) => messages . push ( 'clickload' ) ) ,
111
- page . waitForEvent ( 'load' ) . then ( ( ) => messages . push ( 'load' ) ) ,
112
- ] ) ;
113
- expect ( messages . join ( '|' ) ) . toBe ( 'route|load|clickload' ) ;
114
- } ) ;
115
-
116
131
it ( 'should work with goto following click' , async ( { page, server } ) => {
117
132
server . setRoute ( '/login.html' , async ( req , res ) => {
118
133
res . setHeader ( 'Content-Type' , 'text/html' ) ;
@@ -130,17 +145,6 @@ it('should work with goto following click', async ({ page, server }) => {
130
145
await page . goto ( server . EMPTY_PAGE ) ;
131
146
} ) ;
132
147
133
- it ( 'should report navigation in the log when clicking anchor' , async ( { page, server, mode } ) => {
134
- it . skip ( mode !== 'default' ) ;
135
-
136
- await page . setContent ( `<a href="${ server . PREFIX + '/frames/one-frame.html' } ">click me</a>` ) ;
137
- const __testHookAfterPointerAction = ( ) => new Promise ( f => setTimeout ( f , 6000 ) ) ;
138
- const error = await page . click ( 'a' , { timeout : 5000 , __testHookAfterPointerAction } as any ) . catch ( e => e ) ;
139
- expect ( error . message ) . toContain ( 'page.click: Timeout 5000ms exceeded.' ) ;
140
- expect ( error . message ) . toContain ( 'waiting for scheduled navigations to finish' ) ;
141
- expect ( error . message ) . toContain ( `navigated to "${ server . PREFIX + '/frames/one-frame.html' } "` ) ;
142
- } ) ;
143
-
144
148
it ( 'should report and collapse log in action' , async ( { page, server, mode } ) => {
145
149
await page . setContent ( `<input id='checkbox' type='checkbox' style="visibility: hidden"></input>` ) ;
146
150
const error = await page . locator ( 'input' ) . click ( { timeout : 5000 } ) . catch ( e => e ) ;
0 commit comments