@@ -8,6 +8,7 @@ const assert = require('assert');
8
8
const repl = require ( 'internal/repl' ) ;
9
9
const stream = require ( 'stream' ) ;
10
10
const fs = require ( 'fs' ) ;
11
+ const { setTimeout } = require ( 'timers/promises' ) ;
11
12
12
13
class ActionStream extends stream . Stream {
13
14
run ( data ) {
@@ -53,6 +54,23 @@ function cleanupTmpFile() {
53
54
return true ;
54
55
}
55
56
57
+ // Helper function to wait for a condition with a retry mechanism
58
+ // This should fix flakiness in the REPL tests, due to its nature
59
+ const kMaxRetries = 3 ;
60
+ async function pollForCondition ( assertionFn ) {
61
+ for ( let retries = 0 ; retries <= kMaxRetries ; retries ++ ) {
62
+ try {
63
+ assertionFn ( ) ;
64
+ return ;
65
+ } catch ( err ) {
66
+ if ( retries === kMaxRetries ) {
67
+ throw err ;
68
+ }
69
+ await setTimeout ( 50 ) ;
70
+ }
71
+ }
72
+ }
73
+
56
74
const tmpdir = require ( '../common/tmpdir' ) ;
57
75
tmpdir . refresh ( ) ;
58
76
const defaultHistoryPath = tmpdir . resolve ( '.node_repl_history' ) ;
@@ -62,7 +80,7 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
62
80
// Make sure the cursor is at the right places.
63
81
// If the cursor is at the end of a long line and the down key is pressed,
64
82
// Move the cursor to the end of the next line, if shorter.
65
- const checkResults = common . mustSucceed ( ( r ) => {
83
+ const checkResults = common . mustSucceed ( async ( r ) => {
66
84
r . write ( 'let str = `' ) ;
67
85
r . input . run ( [ { name : 'enter' } ] ) ;
68
86
r . write ( '111' ) ;
@@ -72,28 +90,28 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
72
90
r . write ( '3`' ) ;
73
91
r . input . run ( [ { name : 'enter' } ] ) ;
74
92
r . input . run ( [ { name : 'up' } ] ) ;
75
- assert . strictEqual ( r . cursor , 33 ) ;
93
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 33 ) ) ;
76
94
77
95
r . input . run ( [ { name : 'up' } ] ) ;
78
- assert . strictEqual ( r . cursor , 18 ) ;
96
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 18 ) ) ;
79
97
80
98
for ( let i = 0 ; i < 5 ; i ++ ) {
81
99
r . input . run ( [ { name : 'right' } ] ) ;
82
100
}
83
101
r . input . run ( [ { name : 'up' } ] ) ;
84
- assert . strictEqual ( r . cursor , 15 ) ;
102
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 15 ) ) ;
85
103
r . input . run ( [ { name : 'up' } ] ) ;
86
104
87
105
for ( let i = 0 ; i < 5 ; i ++ ) {
88
106
r . input . run ( [ { name : 'right' } ] ) ;
89
107
}
90
- assert . strictEqual ( r . cursor , 8 ) ;
108
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 8 ) ) ;
91
109
92
110
r . input . run ( [ { name : 'down' } ] ) ;
93
- assert . strictEqual ( r . cursor , 15 ) ;
111
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 15 ) ) ;
94
112
95
113
r . input . run ( [ { name : 'down' } ] ) ;
96
- assert . strictEqual ( r . cursor , 19 ) ;
114
+ await pollForCondition ( ( ) => assert . strictEqual ( r . cursor , 19 ) ) ;
97
115
} ) ;
98
116
99
117
repl . createInternalRepl (
@@ -115,7 +133,7 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
115
133
cleanupTmpFile ( ) ;
116
134
// If the last command errored and the user is trying to edit it,
117
135
// The errored line should be removed from history
118
- const checkResults = common . mustSucceed ( ( r ) => {
136
+ const checkResults = common . mustSucceed ( async ( r ) => {
119
137
r . write ( 'let lineWithMistake = `I have some' ) ;
120
138
r . input . run ( [ { name : 'enter' } ] ) ;
121
139
r . write ( 'problem with` my syntax\'' ) ;
@@ -129,9 +147,18 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
129
147
r . input . run ( [ { name : 'backspace' } ] ) ;
130
148
r . input . run ( [ { name : 'enter' } ] ) ;
131
149
132
- assert . strictEqual ( r . history . length , 1 ) ;
133
- assert . strictEqual ( r . history [ 0 ] , 'let lineWithMistake = `I have some\rproblem with my syntax`' ) ;
134
- assert . strictEqual ( r . line , '' ) ;
150
+ await pollForCondition ( ( ) => assert . strictEqual ( r . history . length , 1 ) ) ;
151
+ // Check that the line is properly set in the history structure
152
+ await pollForCondition ( ( ) => assert . strictEqual ( r . history [ 0 ] ,
153
+ 'problem with my syntax`\rlet lineWithMistake = `I have some' )
154
+ ) ;
155
+ await pollForCondition ( ( ) => assert . strictEqual ( r . line , '' ) ) ;
156
+
157
+ r . input . run ( [ { name : 'up' } ] ) ;
158
+ // Check that the line is properly displayed
159
+ await pollForCondition ( ( ) => assert . strictEqual ( r . line ,
160
+ 'let lineWithMistake = `I have some\nproblem with my syntax`' )
161
+ ) ;
135
162
} ) ;
136
163
137
164
repl . createInternalRepl (
@@ -155,7 +182,7 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
155
182
156
183
// Test that the REPL preview is properly shown on multiline commands
157
184
// And deleted when enter is pressed
158
- const checkResults = common . mustSucceed ( ( r ) => {
185
+ const checkResults = common . mustSucceed ( async ( r ) => {
159
186
r . write ( 'Array(100).fill(' ) ;
160
187
r . input . run ( [ { name : 'enter' } ] ) ;
161
188
r . write ( '123' ) ;
@@ -165,9 +192,9 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
165
192
r . input . run ( [ { name : 'up' } ] ) ;
166
193
r . input . run ( [ { name : 'up' } ] ) ;
167
194
168
- assert . deepStrictEqual ( r . last , new Array ( 100 ) . fill ( 123 ) ) ;
195
+ await pollForCondition ( ( ) => assert . deepStrictEqual ( r . last , new Array ( 100 ) . fill ( 123 ) ) ) ;
169
196
r . input . run ( [ { name : 'enter' } ] ) ;
170
- assert . strictEqual ( outputBuffer . includes ( '[\n' +
197
+ await pollForCondition ( ( ) => assert . strictEqual ( outputBuffer . includes ( '[\n' +
171
198
' 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,\n' +
172
199
' 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,\n' +
173
200
' 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,\n' +
@@ -178,7 +205,7 @@ const defaultHistoryPath = tmpdir.resolve('.node_repl_history');
178
205
' 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,\n' +
179
206
' 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,\n' +
180
207
' 123\n' +
181
- ']\n' ) , true ) ;
208
+ ']\n' ) , true ) ) ;
182
209
} ) ;
183
210
184
211
repl . createInternalRepl (
0 commit comments