@auxcode/auxta 1.3.134 → 1.3.136

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.
@@ -293,9 +293,12 @@ class FunctionHelper extends extend_default_page_1.ExtendDefaultPage {
293
293
  let outcome;
294
294
  try {
295
295
  const handle = yield loginPage.waitForFunction((checkbox, error) => {
296
+ var _a, _b;
296
297
  const errorElement = document.querySelector(error);
297
298
  if (errorElement && errorElement.offsetParent !== null)
298
299
  return 'error';
300
+ if (/AADSTS\d+/.test((_b = (_a = document.body) === null || _a === void 0 ? void 0 : _a.innerText) !== null && _b !== void 0 ? _b : ''))
301
+ return 'error';
299
302
  if (document.querySelector(checkbox))
300
303
  return 'prompt';
301
304
  if (!/(^|\.)(login\.microsoftonline\.com|login\.live\.com)$/.test(location.hostname))
@@ -310,6 +313,9 @@ class FunctionHelper extends extend_default_page_1.ExtendDefaultPage {
310
313
  }
311
314
  if (outcome === 'error') {
312
315
  yield this.failOnMicrosoftLoginError(loginPage, login_error);
316
+ const message = `The microsoft login showed an error after the password step (${yield (0, extend_default_page_1.describePageFailure)(loginPage, 'error page')})`;
317
+ this.log('Then', message, AuxTA_1.StepStatus.FAILED);
318
+ throw new Error(message);
313
319
  }
314
320
  else if (outcome === 'prompt') {
315
321
  yield this.waitForSelector('visible', stay_signed_in_checkbox, this.defaultTimeout, loginPage, false);
@@ -324,10 +330,16 @@ class FunctionHelper extends extend_default_page_1.ExtendDefaultPage {
324
330
  }
325
331
  failOnMicrosoftLoginError(loginPage, login_error) {
326
332
  return __awaiter(this, void 0, void 0, function* () {
333
+ let errorText;
327
334
  const errorElement = yield loginPage.$(login_error);
328
335
  if (errorElement && (yield errorElement.isVisible())) {
329
- const errorText = yield errorElement.evaluate((e) => { var _a; return (_a = e.textContent) === null || _a === void 0 ? void 0 : _a.trim(); });
330
- const message = `The microsoft login shows an error: ${errorText}`;
336
+ errorText = yield errorElement.evaluate((e) => { var _a; return (_a = e.textContent) === null || _a === void 0 ? void 0 : _a.trim(); });
337
+ }
338
+ else {
339
+ errorText = yield loginPage.evaluate(() => { var _a, _b, _c; return (_c = ((_b = (_a = document.body) === null || _a === void 0 ? void 0 : _a.innerText) !== null && _b !== void 0 ? _b : '').match(/AADSTS\d+[^\n]*/)) === null || _c === void 0 ? void 0 : _c[0]; });
340
+ }
341
+ if (errorText) {
342
+ const message = `The microsoft login shows an error: ${errorText} (${(0, extend_default_page_1.pageProblemsSummary)(loginPage)})`;
331
343
  this.log('Then', message, AuxTA_1.StepStatus.FAILED);
332
344
  throw new Error(message);
333
345
  }
@@ -1,4 +1,7 @@
1
1
  export declare function describePageFailure(page: any, error: any): Promise<string>;
2
+ export declare function trackPageProblems(page: any): Promise<void>;
3
+ export declare function pageProblemsSummary(page: any): string;
4
+ export declare function clearPageProblems(page: any): void;
2
5
  export declare class ExtendDefaultPage {
3
6
  defaultTimeout: number;
4
7
  extend_page_functions(page: any, time?: number): Promise<any>;
@@ -14,6 +14,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ExtendDefaultPage = void 0;
16
16
  exports.describePageFailure = describePageFailure;
17
+ exports.trackPageProblems = trackPageProblems;
18
+ exports.pageProblemsSummary = pageProblemsSummary;
19
+ exports.clearPageProblems = clearPageProblems;
17
20
  const log_service_1 = __importDefault(require("../../auxta/services/log.service"));
18
21
  const status_of_step_1 = require("../../auxta/enums/status-of.step");
19
22
  const config_1 = require("../../auxta/configs/config");
@@ -30,11 +33,71 @@ function describePageFailure(page, error) {
30
33
  catch (e) {
31
34
  text = `(page text unavailable: ${String((_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : e).split('\n')[0]})`;
32
35
  }
33
- const details = `reason: ${reason} | url: ${url} | page text: ${text}`;
36
+ const details = `reason: ${reason} | url: ${url} | page text: ${text} | ${pageProblemsSummary(page)}`;
34
37
  console.log(`${new Date().toISOString()} Failure details -- ${details}`);
35
38
  return details;
36
39
  });
37
40
  }
41
+ const MAX_TRACKED_PROBLEMS = 50;
42
+ function pushLimited(list, entry) {
43
+ list.push(entry);
44
+ if (list.length > MAX_TRACKED_PROBLEMS)
45
+ list.shift();
46
+ }
47
+ function trackPageProblems(page) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ if (page.__auxtaFailedRequests)
50
+ return;
51
+ page.__auxtaFailedRequests = [];
52
+ page.__auxtaConsoleErrors = [];
53
+ page.on('console', (message) => {
54
+ const text = message.text();
55
+ if (message.type() === 'error' && !text.startsWith('Refused to apply inline style')) {
56
+ pushLimited(page.__auxtaConsoleErrors, `${new Date().toISOString()} ${text.slice(0, 200)}`);
57
+ }
58
+ });
59
+ page.on('pageerror', (error) => {
60
+ var _a;
61
+ pushLimited(page.__auxtaConsoleErrors, `${new Date().toISOString()} uncaught: ${String((_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error).slice(0, 200)}`);
62
+ });
63
+ try {
64
+ const cdp = yield page.createCDPSession();
65
+ const requests = new Map();
66
+ cdp.on('Network.requestWillBeSent', (event) => requests.set(event.requestId, event.request.url));
67
+ cdp.on('Network.loadingFinished', (event) => requests.delete(event.requestId));
68
+ cdp.on('Network.loadingFailed', (event) => {
69
+ var _a, _b;
70
+ const why = [
71
+ event.type,
72
+ event.canceled ? 'canceled' : '',
73
+ event.blockedReason ? `blocked: ${event.blockedReason}` : '',
74
+ ((_a = event.corsErrorStatus) === null || _a === void 0 ? void 0 : _a.corsError) ? `cors: ${event.corsErrorStatus.corsError}` : ''
75
+ ].filter(Boolean).join(', ');
76
+ pushLimited(page.__auxtaFailedRequests, `${new Date().toISOString()} ${event.errorText} (${why}) ${(_b = requests.get(event.requestId)) !== null && _b !== void 0 ? _b : event.requestId}`);
77
+ requests.delete(event.requestId);
78
+ });
79
+ yield cdp.send('Network.enable');
80
+ }
81
+ catch (e) {
82
+ page.on('requestfailed', (request) => {
83
+ var _a, _b;
84
+ pushLimited(page.__auxtaFailedRequests, `${new Date().toISOString()} ${(_b = (_a = request.failure()) === null || _a === void 0 ? void 0 : _a.errorText) !== null && _b !== void 0 ? _b : 'unknown error'} ${request.url()}`);
85
+ });
86
+ }
87
+ });
88
+ }
89
+ function pageProblemsSummary(page) {
90
+ var _a, _b;
91
+ const failedRequests = ((_a = page.__auxtaFailedRequests) !== null && _a !== void 0 ? _a : []).slice(-10).join(', ') || 'none';
92
+ const consoleErrors = ((_b = page.__auxtaConsoleErrors) !== null && _b !== void 0 ? _b : []).slice(-5).join(', ') || 'none';
93
+ return `failed requests: ${failedRequests} | console errors: ${consoleErrors}`;
94
+ }
95
+ function clearPageProblems(page) {
96
+ if (page.__auxtaFailedRequests)
97
+ page.__auxtaFailedRequests.length = 0;
98
+ if (page.__auxtaConsoleErrors)
99
+ page.__auxtaConsoleErrors.length = 0;
100
+ }
38
101
  class ExtendDefaultPage {
39
102
  constructor() {
40
103
  this.defaultTimeout = config_1.config.timeout;
@@ -42,6 +105,7 @@ class ExtendDefaultPage {
42
105
  extend_page_functions(page_1) {
43
106
  return __awaiter(this, arguments, void 0, function* (page, time = this.defaultTimeout) {
44
107
  this.defaultTimeout = config_1.config.timeout;
108
+ yield trackPageProblems(page);
45
109
  const { goto: original_goto, click: original_click, type: original_type, waitForNetworkIdle: original_waitForNetworkIdle } = page;
46
110
  page.goto = function goto(url, options) {
47
111
  log_service_1.default.push('Then', log_service_1.default.tag, `I go to the '${url}' page`, status_of_step_1.StatusOfStep.PASSED);
@@ -15,6 +15,8 @@ export declare class Puppeteer {
15
15
  private _tabLogs;
16
16
  private static setupHeader;
17
17
  startBrowser(): Promise<void>;
18
+ private static printBrowserErrors;
19
+ private reloadIfBlank;
18
20
  close(): Promise<void>;
19
21
  private initiateBrowser;
20
22
  private logFail;
@@ -20,6 +20,7 @@ const AuxTA_1 = __importDefault(require("../AuxTA"));
20
20
  const status_of_step_1 = require("../auxta/enums/status-of.step");
21
21
  const config_1 = require("../auxta/configs/config");
22
22
  const start_suite_helper_1 = require("../auxta/utilities/start-suite.helper");
23
+ const extend_default_page_1 = require("../macros/helpers/extend-default-page");
23
24
  const puppeteer = require("puppeteer");
24
25
  class Puppeteer {
25
26
  constructor() {
@@ -167,10 +168,46 @@ class Puppeteer {
167
168
  },
168
169
  headless: process.env.ENVIRONMENT === 'LOCAL' ? (process.env.headless === 'true') : true
169
170
  });
171
+ Puppeteer.printBrowserErrors(this.browser);
170
172
  this.defaultPage = (yield this.browser.pages())[0];
171
173
  yield AuxTA_1.default.extend_page_functions(this.defaultPage);
172
174
  yield this.defaultPage.goto(config_1.config.baseURL, { waitUntil: 'networkidle0' });
173
175
  yield this.defaultPage.waitForNetworkIdle();
176
+ yield this.reloadIfBlank(this.defaultPage);
177
+ });
178
+ }
179
+ static printBrowserErrors(browser, maxLines = 100) {
180
+ var _a, _b;
181
+ const important = /crash|network service|fatal|out of memory|oom|disk_cache|cache|shared_memory|shm|net_error|ERR_/i;
182
+ const noise = /dbus|bus\.cc|gpu_init|viz_main|fontconfig/i;
183
+ let printed = 0;
184
+ let buffer = '';
185
+ (_b = (_a = browser.process()) === null || _a === void 0 ? void 0 : _a.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
186
+ var _a;
187
+ buffer += data.toString();
188
+ const lines = buffer.split('\n');
189
+ buffer = (_a = lines.pop()) !== null && _a !== void 0 ? _a : '';
190
+ for (const line of lines) {
191
+ if (printed >= maxLines || !important.test(line) || noise.test(line))
192
+ continue;
193
+ printed++;
194
+ console.log(`${new Date().toISOString()} Chrome: ${line.trim().slice(0, 300)}`);
195
+ }
196
+ });
197
+ }
198
+ reloadIfBlank(page_1) {
199
+ return __awaiter(this, arguments, void 0, function* (page, retries = 2, renderTimeout = 10000) {
200
+ for (let attempt = 1; attempt <= retries; attempt++) {
201
+ const rendered = yield page.waitForFunction(() => !!document.body && (document.body.innerText.trim().length > 0 || !!document.querySelector('button, input, a[href]')), { timeout: renderTimeout, polling: 500 }).then(() => true, () => false);
202
+ if (rendered)
203
+ return;
204
+ const message = `The page ${page.url()} stayed blank after loading, reloading it (attempt ${attempt} of ${retries}, ${(0, extend_default_page_1.pageProblemsSummary)(page)})`;
205
+ console.log(`${new Date().toISOString()} ${message}`);
206
+ log_service_1.default.push('When', log_service_1.default.tag, message, status_of_step_1.StatusOfStep.LOG);
207
+ (0, extend_default_page_1.clearPageProblems)(page);
208
+ yield page.reload({ waitUntil: 'networkidle0' });
209
+ yield page.waitForNetworkIdle();
210
+ }
174
211
  });
175
212
  }
176
213
  close() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auxcode/auxta",
3
- "version": "1.3.134",
3
+ "version": "1.3.136",
4
4
  "description": "",
5
5
  "main": "./build/AuxTA.js",
6
6
  "types": "./build/AuxTA.d.ts",