@skyramp/skyramp 1.2.23 → 1.2.25
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/package.json
CHANGED
|
@@ -267,4 +267,11 @@ export declare class SkyrampClient {
|
|
|
267
267
|
scenario: AsyncScenario | AsyncScenario[],
|
|
268
268
|
options?: SendScenarioOptions
|
|
269
269
|
): Promise<AsyncTestStatus>;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Fetches OTP from Skyramp email
|
|
273
|
+
*/
|
|
274
|
+
fetchLatestOtp(
|
|
275
|
+
email: string
|
|
276
|
+
): string;
|
|
270
277
|
}
|
|
@@ -3,6 +3,7 @@ const koffi = require('koffi');
|
|
|
3
3
|
const TrafficConfig = require('./TrafficConfig');
|
|
4
4
|
const RequestV2 = require('./RequestV2');
|
|
5
5
|
const ResponseV2 = require('./ResponseV2');
|
|
6
|
+
const utils = require('../utils');
|
|
6
7
|
|
|
7
8
|
const workerInfoType = koffi.struct({
|
|
8
9
|
container_name: 'char*',
|
|
@@ -99,6 +100,7 @@ class SkyrampClient {
|
|
|
99
100
|
*/
|
|
100
101
|
constructor(kubeconfigPathOrOptions, clusterName, context, userToken, directory = process.cwd()) {
|
|
101
102
|
this.local_image = false;
|
|
103
|
+
this.timestamp = Date.now();
|
|
102
104
|
if (typeof kubeconfigPathOrOptions === 'object') {
|
|
103
105
|
const options = kubeconfigPathOrOptions;
|
|
104
106
|
this.workerNamespaces = [];
|
|
@@ -966,6 +968,38 @@ class SkyrampClient {
|
|
|
966
968
|
);
|
|
967
969
|
});
|
|
968
970
|
}
|
|
971
|
+
|
|
972
|
+
async fetchLatestOtp(email) {
|
|
973
|
+
var latestGetResponse
|
|
974
|
+
// we use the time that this client was instantiated
|
|
975
|
+
let timestamp = this.timestamp;
|
|
976
|
+
|
|
977
|
+
if (!email.includes("@otp.skyramp.dev")) {
|
|
978
|
+
throw new Error("non-Skyramp email is not supported")
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
const username = email.replace("@otp.skyramp.dev", "")
|
|
982
|
+
|
|
983
|
+
for (let i = 0; i < 10; i ++) {
|
|
984
|
+
// Execute Request
|
|
985
|
+
latestGetResponse = await this.sendRequest({
|
|
986
|
+
url: "https://tokenize.skyramp.dev",
|
|
987
|
+
path: `/msg/${username}/latest`,
|
|
988
|
+
method: "GET"
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
if (latestGetResponse.statusCode != 200) {
|
|
992
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
993
|
+
continue
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
let codeTime = new Date(utils.getValue(latestGetResponse.responseBody, "timestamp"));
|
|
997
|
+
if (codeTime > timestamp) {
|
|
998
|
+
return utils.getValue(latestGetResponse.responseBody, "otp")
|
|
999
|
+
}
|
|
1000
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
969
1003
|
}
|
|
970
1004
|
|
|
971
1005
|
module.exports = SkyrampClient;
|
|
@@ -143,8 +143,6 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
143
143
|
let pageTitle = await skyrampLocator.page().title();
|
|
144
144
|
let pageUrl = skyrampLocator.page().url();
|
|
145
145
|
|
|
146
|
-
debug("retry with LLM", skyrampLocator._locator);
|
|
147
|
-
|
|
148
146
|
let newMsg = `${errorMessage} (while using selector: ${locatorStr})`;
|
|
149
147
|
|
|
150
148
|
let pageContent = await skyrampLocator.page().content();
|
|
@@ -167,7 +165,7 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
167
165
|
}
|
|
168
166
|
|
|
169
167
|
if (suggestions == null || suggestions.length == 0) {
|
|
170
|
-
debug("No LLM
|
|
168
|
+
debug("No LLM suggestions available, failing with original error");
|
|
171
169
|
throw error;
|
|
172
170
|
}
|
|
173
171
|
|
|
@@ -175,7 +173,6 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
175
173
|
debug(suggestions)
|
|
176
174
|
|
|
177
175
|
for (let suggestion of suggestions) {
|
|
178
|
-
debug(`try ${suggestion.selector} instead of ${skyrampLocator._locator}`);
|
|
179
176
|
try {
|
|
180
177
|
const newLocator = skyrampLocator.createLocatorFromString(suggestion.selector);
|
|
181
178
|
if (newLocator == null) {
|
|
@@ -184,7 +181,7 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
184
181
|
|
|
185
182
|
const locatorCount = await newLocator.count();
|
|
186
183
|
|
|
187
|
-
debug(`
|
|
184
|
+
debug(`trying new Locator ${newLocator} instead of ${skyrampLocator._locator}, count = ${locatorCount}`);
|
|
188
185
|
|
|
189
186
|
if (locatorCount == 1) {
|
|
190
187
|
const func = newLocator[skyrampLocator.execFname];
|
|
@@ -197,7 +194,8 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
197
194
|
skyrampLocator._skyrampPage.addLLMChoices(skyrampLocator._locator, newLocator, error.stack);
|
|
198
195
|
return result;
|
|
199
196
|
}).catch(error => {
|
|
200
|
-
|
|
197
|
+
// if it fails, move to the next one
|
|
198
|
+
debug(`retrying with LLM failed at ${skyrampLocator._locator} replaced by {newLocator}`, error.name);
|
|
201
199
|
});
|
|
202
200
|
}
|
|
203
201
|
} catch {
|
|
@@ -205,17 +203,18 @@ async function retryWithLLM(skyrampLocator, error) {
|
|
|
205
203
|
}
|
|
206
204
|
}
|
|
207
205
|
|
|
208
|
-
|
|
206
|
+
error.message = `Failed to find a good alternative for ${skyrampLocator._locator} with LLM.\n` +
|
|
207
|
+
`Please add "data-testid" attribute for a more stable locator\n` + error.message;
|
|
208
|
+
throw error;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
class SkyrampPlaywrightLocator {
|
|
212
|
-
constructor(skyrampPage, locator, prevLocator, args, options
|
|
212
|
+
constructor(skyrampPage, locator, prevLocator, args, options) {
|
|
213
213
|
this._skyrampPage = skyrampPage
|
|
214
214
|
this._locator = locator
|
|
215
215
|
this._previousLocator = prevLocator
|
|
216
216
|
this._args = args
|
|
217
217
|
this._options = options
|
|
218
|
-
this._hydration = hydration || false
|
|
219
218
|
return new Proxy(this, {
|
|
220
219
|
get(wrapper, prop, receiver) {
|
|
221
220
|
// First, check if the property exists on the wrapper.
|
|
@@ -237,16 +236,8 @@ class SkyrampPlaywrightLocator {
|
|
|
237
236
|
});
|
|
238
237
|
}
|
|
239
238
|
|
|
240
|
-
isHydration() {
|
|
241
|
-
return this._hydration
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
isPrevHydration() {
|
|
245
|
-
return this._previousLocator && this._previousLocator.isHydration()
|
|
246
|
-
}
|
|
247
|
-
|
|
248
239
|
async execute() {
|
|
249
|
-
debug(`execute ${ this._locator}.${this.execFname} ${this.execParam ?? ''} ${this.execArgs ?? ''}`)
|
|
240
|
+
debug(` execute ${ this._locator}.${this.execFname} ${this.execParam ?? ''} ${this.execArgs ?? ''}`)
|
|
250
241
|
const func = this._locator[this.execFname];
|
|
251
242
|
return func.call(this._locator, this.execParam, this.execArgs);
|
|
252
243
|
}
|
|
@@ -268,69 +259,119 @@ class SkyrampPlaywrightLocator {
|
|
|
268
259
|
return ret;
|
|
269
260
|
}
|
|
270
261
|
|
|
271
|
-
|
|
262
|
+
wrapError(msg, error) {
|
|
263
|
+
let newMsg = msg;
|
|
264
|
+
if (this._skyrampPage.hasLLMChoices()) {
|
|
265
|
+
newMsg += this.generateLLMErrors();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
error.message = error.message + "\n" + newMsg
|
|
269
|
+
|
|
270
|
+
return error
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
hydrationErrorMsg = "Potentially a hydration issue. Please add enough waitForTimeout()"
|
|
274
|
+
|
|
275
|
+
newPrevHyrdationErrorMsg() {
|
|
276
|
+
return `Cannot find locator ${this._locator} and likely a hydration issue on ${this._previousLocator._locator}.\n` +
|
|
277
|
+
`Please add enough waitForTimeout() on ${this._previoousLocator._locator}`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
newMultiLocatorErrorMsg() {
|
|
281
|
+
return `${this._locator} found ${this.locatorCount} locators. Please add "data-testid" attribute for a more stable locator`
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async _retryWithLLM(error, msg1) {
|
|
285
|
+
// if API_KEY is not defined, throw an error here without trying
|
|
286
|
+
if (!process.env.API_KEY) {
|
|
287
|
+
error.message = msg1 + error.message;
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
debug(` try to get suggessions from LLM for ${this._locator}`);
|
|
292
|
+
return retryWithLLM(this, error).then(result => {
|
|
293
|
+
this.LLMselector = true;
|
|
294
|
+
return result;
|
|
295
|
+
}).catch(newError => {
|
|
296
|
+
throw this.wrapError("", newError)
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
272
300
|
async SmartRetryWithFallback(fname, param, ...args) {
|
|
273
301
|
this.execFname = fname;
|
|
274
302
|
this.execParam = param;
|
|
275
303
|
this.execArgs = args;
|
|
276
304
|
|
|
277
305
|
let locatorCount = await this._locator.count();
|
|
278
|
-
|
|
306
|
+
let currentUrl = this._skyrampPage._page.url();
|
|
307
|
+
debug(`handling ${ this._locator }.${ fname }, count = ${ locatorCount }, ${currentUrl}`);
|
|
279
308
|
this.locatorCount = locatorCount
|
|
280
309
|
|
|
281
|
-
|
|
282
|
-
debug(`current url = ${currentUrl}`);
|
|
310
|
+
//debug(`current url = ${currentUrl}`);
|
|
283
311
|
|
|
284
312
|
// if locator exists, DOM is available
|
|
285
313
|
if (locatorCount == 1) {
|
|
314
|
+
debug(` single locator for ${this._locator} identified, ${currentUrl}`);
|
|
286
315
|
// we try action, this will most likely succeed
|
|
287
316
|
// if it fails, there could be potentially a hydration issue we can retry after a little wait time
|
|
288
|
-
|
|
289
|
-
|
|
317
|
+
try {
|
|
318
|
+
return await this.execute().then(result => {
|
|
319
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
320
|
+
});
|
|
321
|
+
} catch (error) {
|
|
322
|
+
debug(` first attempt of ${this._locator} failed, ${error.name}`);
|
|
290
323
|
if (error.name == "TimeoutError") {
|
|
291
|
-
|
|
292
|
-
|
|
324
|
+
// this is likely a hydration issue
|
|
325
|
+
// we wait a bit and retry
|
|
326
|
+
debug(` locator ${this._locator} exists, but execution failed, wait a bit and try again`);
|
|
327
|
+
await this.wait(defaultWaitForTimeout);
|
|
328
|
+
|
|
329
|
+
// Is this really necessary?
|
|
330
|
+
await this.execute().then(result => {
|
|
331
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
332
|
+
}).catch(() => {
|
|
333
|
+
debug(` failed second time and execute previous locator ${this._previousLocator._locator} again`);
|
|
334
|
+
this._previousLocator.execute();
|
|
335
|
+
}).catch(() => {
|
|
336
|
+
debug(` failed to execute previous locator ${this._previousLocator._locator} again, continue`);
|
|
337
|
+
});
|
|
293
338
|
|
|
294
339
|
return this.execute().catch(newError => {
|
|
295
|
-
debug(`
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
newError
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
340
|
+
debug(` third attempt on ${this._locator} failed ${newError.name}`);
|
|
341
|
+
if (newError.name == "TimeoutError") {
|
|
342
|
+
// this hadn't happened yet. we need to validate if this is indeed hydration case
|
|
343
|
+
return this._retryWithLLM(newError, this.hydrationErrorMsg)
|
|
344
|
+
}
|
|
345
|
+
if (newError.message.includes("strict mode violation")) {
|
|
346
|
+
return this._retryWithLLM(newError, this.newMultiLocatorErrorMsg());
|
|
302
347
|
}
|
|
348
|
+
throw error;
|
|
303
349
|
});
|
|
304
350
|
}
|
|
351
|
+
if (error.message.includes("strict mode violation")) {
|
|
352
|
+
return this._retryWithLLM(error, this.newMultiLocatorErrorMsg());
|
|
353
|
+
}
|
|
354
|
+
// we do not handle the rest of the error cases, but simply forward error
|
|
305
355
|
throw error;
|
|
306
|
-
}
|
|
356
|
+
}
|
|
307
357
|
} else if (locatorCount > 0) {
|
|
308
|
-
|
|
309
|
-
|
|
358
|
+
debug(` multiple ${locatorCount} locators for ${this._locator} identified, ${currentUrl}`);
|
|
359
|
+
// wait a bit and retry before consulting with LLM
|
|
360
|
+
await this.wait(defaultWaitForTimeout);
|
|
361
|
+
|
|
362
|
+
locatorCount = await this._locator.count();
|
|
363
|
+
this.locatorCount = locatorCount
|
|
310
364
|
|
|
311
365
|
if (locatorCount > 5) {
|
|
366
|
+
// we fail even without trying
|
|
312
367
|
throw new Error(`${locatorCount} locators detected for ${this._locator}. Please add "data-testid" attribute for a more stable locator`);
|
|
313
368
|
}
|
|
314
369
|
|
|
370
|
+
// this will likely fail, but we try to get error message generated by playwright
|
|
315
371
|
return this.execute().then(result => {
|
|
316
|
-
return result;
|
|
372
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
317
373
|
}).catch(error => {
|
|
318
|
-
|
|
319
|
-
throw new Error(`${locatorCount} locators detected for ${this._locator}. Please add "data-testid" attribute for a more stable locator`, error)
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
console.log(`${locatorCount} locators found for ${this._locator}`)
|
|
323
|
-
// this is the palce where we consult with LLM
|
|
324
|
-
return retryWithLLM(this, error).then(result => {
|
|
325
|
-
this.multiLocatorLLM = true;
|
|
326
|
-
return result;
|
|
327
|
-
}).catch(newError => {
|
|
328
|
-
if (this._skyrampPage.hasLLMChoices()) {
|
|
329
|
-
newError.message += this.generateLLMErrors();
|
|
330
|
-
throw newError;
|
|
331
|
-
}
|
|
332
|
-
throw new Error(`failed to find a good alternative for ${this._locator}. Please add "data-testid" attribute for a more stable locator`, newError);
|
|
333
|
-
});
|
|
374
|
+
return this._retryWithLLM(error, this.newMultiLocatorErrorMsg());
|
|
334
375
|
});
|
|
335
376
|
} else {
|
|
336
377
|
// if locator does not exist, we need to consider two cases
|
|
@@ -338,54 +379,44 @@ class SkyrampPlaywrightLocator {
|
|
|
338
379
|
// second, if locator id is not correct
|
|
339
380
|
// check if last step has potential hydration
|
|
340
381
|
if (this._previousLocator && this._previousLocator.locatorCount == 0) {
|
|
341
|
-
debug(`previous action ${this._previousLocator._locator} is potentially associated with hydration`);
|
|
382
|
+
debug(` previous action ${this._previousLocator._locator} is potentially associated with hydration, ${currentUrl}`);
|
|
342
383
|
// wait for a short time to finish hydration
|
|
343
384
|
await this.wait(defaultWaitForTimeout);
|
|
344
|
-
|
|
345
385
|
const previousCount = await this._previousLocator.count();
|
|
346
|
-
debug(`
|
|
347
|
-
|
|
386
|
+
debug(` re-execute the previous one ${this._previousLocator._locator}, new locator count = ${previousCount}, ${currentUrl}`);
|
|
348
387
|
// re-execute the previous locator
|
|
349
388
|
await this._previousLocator.execute().catch(() => {
|
|
350
389
|
// log the failure but continues to the current one
|
|
351
|
-
debug(`failed to execute previous locator ${this._previousLocator._locator} again`);
|
|
390
|
+
debug(` failed to execute previous locator ${this._previousLocator._locator} again, continue`);
|
|
352
391
|
});
|
|
353
392
|
|
|
354
393
|
try {
|
|
355
394
|
// then execute the current one
|
|
356
|
-
return await this.execute()
|
|
395
|
+
return await this.execute().then(result => {
|
|
396
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
397
|
+
});
|
|
357
398
|
} catch (error) {
|
|
358
399
|
if (error.name == "TimeoutError") {
|
|
359
|
-
debug(
|
|
400
|
+
debug(` ${this._locator} failed at first try. attempting again with some timeout`);
|
|
360
401
|
// wait for some time and re execute
|
|
361
402
|
await this.wait(defaultWaitForTimeout);
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
// retry with llm
|
|
368
|
-
return retryWithLLM(this, newError).then(result => {
|
|
369
|
-
this.singleLocatorLLM = true;
|
|
370
|
-
return result;
|
|
371
|
-
}).catch(newError2 => {
|
|
372
|
-
if (this._skyrampPage.hasLLMChoices()) {
|
|
373
|
-
newError2.message += this.generateLLMErrors();
|
|
374
|
-
throw newError2;
|
|
375
|
-
}
|
|
376
|
-
throw new Error(`Failed to find a good alternative of ${this._locator}. Please add "data-testid" attribute for a more stable locator`, newError2);
|
|
377
|
-
});
|
|
403
|
+
return this.execute().then(result => {
|
|
404
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
405
|
+
}).catch(newError => {
|
|
406
|
+
return this._retryWithLLM(newError, this.newPrevHydrationErrorMsg());
|
|
378
407
|
});
|
|
379
408
|
}
|
|
409
|
+
if (error.message.includes("strict mode violation")) {
|
|
410
|
+
debug(` a rare case when multiple locators are detected on ${this._locator}`);
|
|
411
|
+
return this._retryWithLLM(error, this.newMultiLocatorErrorMsg());
|
|
412
|
+
}
|
|
380
413
|
throw error;
|
|
381
414
|
}
|
|
382
415
|
} else {
|
|
383
|
-
if (this._previousLocator && this._previousLocator.
|
|
384
|
-
debug(
|
|
385
|
-
} else if (this._previousLocator && this._previousLocator.singleLocatorLLM) {
|
|
386
|
-
debug(`${this._locator} locator count is zero, but previous locator was selected by LLM from zero candidate`);
|
|
416
|
+
if (this._previousLocator && this._previousLocator.LLMselector) {
|
|
417
|
+
debug(` ${this._locator} locator count is zero, but previous locator was selected by LLM`);
|
|
387
418
|
} else {
|
|
388
|
-
debug(
|
|
419
|
+
debug(` ${this._locator} locator count is zero, but previous locator seems not related to hydration`);
|
|
389
420
|
}
|
|
390
421
|
// previous action may not be associated with hydration
|
|
391
422
|
// then we just try current locator. could be a locator with a wrong id
|
|
@@ -393,36 +424,32 @@ class SkyrampPlaywrightLocator {
|
|
|
393
424
|
await this.wait(defaultWaitForTimeout);
|
|
394
425
|
|
|
395
426
|
this.locatorCount = await this._locator.count();
|
|
396
|
-
debug(`
|
|
427
|
+
debug(` after waiting locator ${this._locator} count = ${this.locatorCount}, ${currentUrl}`);
|
|
397
428
|
|
|
398
429
|
try {
|
|
399
|
-
return await this.execute()
|
|
430
|
+
return await this.execute().then(result => {
|
|
431
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
432
|
+
});
|
|
400
433
|
} catch (error) {
|
|
401
434
|
if (error.name == "TimeoutError") {
|
|
402
435
|
debug(`${this._locator} failed at first try. attempting again with some timeout`);
|
|
403
436
|
await this.wait(defaultWaitForTimeout);
|
|
404
|
-
|
|
405
|
-
|
|
437
|
+
return this.execute().then(result=> {
|
|
438
|
+
return this._skyrampPage.checkNavigation(currentUrl, result);
|
|
439
|
+
}).catch(newError => {
|
|
406
440
|
if (newError.name == "TimeoutError") {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
return retryWithLLM(this, newError).then(result => {
|
|
412
|
-
this.singleLocatorLLM = true;
|
|
413
|
-
return result;
|
|
414
|
-
}).catch(newError2 => {
|
|
415
|
-
if (this._skyrampPage.hasLLMChoices()) {
|
|
416
|
-
newError2.message += this.generateLLMErrors();
|
|
417
|
-
throw newError2;
|
|
418
|
-
}
|
|
419
|
-
throw new Error(`Failed to find a good alternative of ${this._locator}. Please add "data-testid" attribute for a more stable locator`, newError2);
|
|
420
|
-
});
|
|
421
|
-
} else {
|
|
422
|
-
throw newError;
|
|
441
|
+
return this._retryWithLLM(newError, this.hydrationErrorMsg);
|
|
442
|
+
}
|
|
443
|
+
if (newError.message.includes("strict mode violation")) {
|
|
444
|
+
return this._retryWithLLM(newError, this.newMultiLocatorErrorMsg());
|
|
423
445
|
}
|
|
446
|
+
throw newError;
|
|
424
447
|
});
|
|
425
448
|
}
|
|
449
|
+
// if multiple locator found
|
|
450
|
+
if (this.locatorCount > 1 || error.message.includes("strict mode violation")) {
|
|
451
|
+
return this._retryWithLLM(error, this.newMultiLocatorErrorMsg());
|
|
452
|
+
}
|
|
426
453
|
throw error;
|
|
427
454
|
}
|
|
428
455
|
}
|
|
@@ -613,7 +640,7 @@ class SkyrampPlaywrightLocator {
|
|
|
613
640
|
}
|
|
614
641
|
|
|
615
642
|
async wait(t) {
|
|
616
|
-
debug(`wait for ${t}`);
|
|
643
|
+
debug(` wait for ${t}`);
|
|
617
644
|
return this._skyrampPage._page.waitForTimeout(t);
|
|
618
645
|
}
|
|
619
646
|
}
|
|
@@ -621,7 +648,6 @@ class SkyrampPlaywrightLocator {
|
|
|
621
648
|
class SkyrampPlaywrightPage {
|
|
622
649
|
constructor(page) {
|
|
623
650
|
this._page = page;
|
|
624
|
-
this._curUrl = "";
|
|
625
651
|
return new Proxy(this, {
|
|
626
652
|
// The `get` trap is the key to forwarding.
|
|
627
653
|
// This will foraward any methods not implemented in this struct
|
|
@@ -646,10 +672,6 @@ class SkyrampPlaywrightPage {
|
|
|
646
672
|
});
|
|
647
673
|
}
|
|
648
674
|
|
|
649
|
-
getCurUrl() {
|
|
650
|
-
return this._curUrl;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
675
|
pushLocator(locator) {
|
|
654
676
|
if (this.locators == undefined ) {
|
|
655
677
|
this.locators = [];
|
|
@@ -670,7 +692,6 @@ class SkyrampPlaywrightPage {
|
|
|
670
692
|
|
|
671
693
|
newSkyrampPlaywrightLocator(originalLocator, param, options) {
|
|
672
694
|
let prevLocator = this.getLastLocator();
|
|
673
|
-
const hydration = options && (options.hydration || false);
|
|
674
695
|
/*
|
|
675
696
|
if (prevLocator != null) {
|
|
676
697
|
debug(`handling ${originalLocator} prev ${prevLocator._locator}`);
|
|
@@ -679,7 +700,7 @@ class SkyrampPlaywrightPage {
|
|
|
679
700
|
}
|
|
680
701
|
*/
|
|
681
702
|
|
|
682
|
-
let newLocator = new SkyrampPlaywrightLocator(this, originalLocator, prevLocator, [param], options
|
|
703
|
+
let newLocator = new SkyrampPlaywrightLocator(this, originalLocator, prevLocator, [param], options);
|
|
683
704
|
this.pushLocator(newLocator)
|
|
684
705
|
return newLocator
|
|
685
706
|
}
|
|
@@ -734,7 +755,6 @@ class SkyrampPlaywrightPage {
|
|
|
734
755
|
} else {
|
|
735
756
|
debug(`javascript not detected when visiting ${this._page.url()}`);
|
|
736
757
|
}
|
|
737
|
-
this._curUrl = this._page.url();
|
|
738
758
|
return result;
|
|
739
759
|
}
|
|
740
760
|
|
|
@@ -760,6 +780,15 @@ class SkyrampPlaywrightPage {
|
|
|
760
780
|
}
|
|
761
781
|
return true;
|
|
762
782
|
}
|
|
783
|
+
|
|
784
|
+
async checkNavigation(original, result) {
|
|
785
|
+
const newURL = this._page.url()
|
|
786
|
+
if (newURL != original) {
|
|
787
|
+
debug(`page navigation to ${newURL} detected, wait a bit`);
|
|
788
|
+
await this._page.waitForTimeout(defaultWaitForTimeout);
|
|
789
|
+
}
|
|
790
|
+
return result;
|
|
791
|
+
}
|
|
763
792
|
}
|
|
764
793
|
|
|
765
794
|
function newSkyrampPlaywrightPage(page) {
|