@auxcode/auxta 0.2.0 → 0.2.4

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/README.md CHANGED
@@ -36,9 +36,13 @@ npm i
36
36
  # Default 1000
37
37
  "timeout": 1000,
38
38
  # The credentials of the user that uploads the tests to the site
39
- "email": "",
40
- "password": "",
41
- "token": ""
39
+ "email": "string",
40
+ "password": "string",
41
+ "token": "string"
42
+ # Screen width and height used in the testing
43
+ # Allows testing from mobile devices screens
44
+ "screenWidth": 1920,
45
+ "screenHeight": 1080,
42
46
  }
43
47
 
44
48
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auxcode/auxta",
3
- "version": "0.2.0",
3
+ "version": "0.2.4",
4
4
  "description": "",
5
5
  "main": "src/AuxTA.ts",
6
6
  "scripts": {
package/src/AuxTA.ts CHANGED
@@ -2,10 +2,10 @@ import puppeteer, { Puppeteer } from "./puppeteer/puppeteer";
2
2
  import { FunctionHelper } from "./macros/helpers/code.helper";
3
3
  import path from "path";
4
4
  import fs from "fs";
5
- import StepStatusEnum from "./auxta/enums/step-status.enum";
5
+ import StatusOfStep from "./auxta/enums/status-of.step";
6
6
  import { UploadModel } from "./auxta/models/upload.model";
7
7
  import * as dotenv from "dotenv";
8
- import { config, setupConfig } from "./auxta/configs/config";
8
+ import { setupConfig, config as c, setupOverrideConfig } from "./auxta/configs/config";
9
9
  import { startSuite } from "./auxta/utilities/start-suite.helper";
10
10
  import { createEmptyReport } from "./auxta/services/report.service";
11
11
 
@@ -13,6 +13,7 @@ dotenv.config();
13
13
 
14
14
  class AuxTA extends FunctionHelper {
15
15
  public puppeteer: Puppeteer = puppeteer;
16
+ public config = c;
16
17
 
17
18
  private readonly uploadModel: UploadModel;
18
19
 
@@ -36,7 +37,7 @@ class AuxTA extends FunctionHelper {
36
37
  }
37
38
  const jsonConfig = JSON.parse(fs.readFileSync(file).toString());
38
39
  try {
39
- setupConfig(jsonConfig)
40
+ this.config = setupConfig(jsonConfig)
40
41
  } catch (e: any) {
41
42
  console.log("Missing field in auxta.json:", e.message)
42
43
  }
@@ -48,18 +49,33 @@ class AuxTA extends FunctionHelper {
48
49
  }
49
50
  }
50
51
 
51
- public async run(event: any) {
52
- const model = this.uploadModel;
53
- let token: string = event.queryStringParameters.token;
52
+ public async run(event: any, overrideConfig?: any) {
53
+ this.changeModelData(overrideConfig);
54
54
  let reportId: string | undefined = event.queryStringParameters.reportId;
55
- if (token !== config.token) return {statusCode: 401, message: 'Unauthorized'}
56
- const suites = config.suitesList.slice(0);
57
- await startSuite(suites, reportId || await createEmptyReport(model));
55
+ if (process.env.ENVIRONMENT === 'LIVE' && event.queryStringParameters.token !== this.config.token)
56
+ return {statusCode: 401, message: 'Unauthorized'}
57
+ const suites = this.config.suitesList.slice(0);
58
+ await startSuite(suites, reportId || await createEmptyReport(this.uploadModel));
58
59
  return {statusCode: 204}
59
60
  }
61
+ private changeModelData(overrideConfig?: any){
62
+ if (overrideConfig) {
63
+ if (overrideConfig.digitalProduct) this.uploadModel.digitalProduct = overrideConfig.digitalProduct
64
+ if (overrideConfig.environment) this.uploadModel.environment = overrideConfig.environment
65
+ if (overrideConfig.baseUrl) this.uploadModel.baseUrl = overrideConfig.baseUrl
66
+ this.config = setupOverrideConfig(overrideConfig)
67
+ }
68
+ }
60
69
 
61
- public startBrowser(event: any, callback: any, feature: string, scenario: string) {
62
- this.puppeteer.run(event, callback, feature, scenario)
70
+ public async startBrowser(event: any, callback: any, feature: string, scenario: string, overrideConfig?: any, singleFeature = false) {
71
+ this.changeModelData(overrideConfig);
72
+ if (singleFeature) {
73
+ if (process.env.ENVIRONMENT === 'LIVE' && event.queryStringParameters.token !== this.config.token)
74
+ return {statusCode: 401, message: 'Unauthorized'}
75
+ this.uploadModel.reportId = await createEmptyReport(this.uploadModel);
76
+ this.uploadModel.nextSuites = [];
77
+ }
78
+ return this.puppeteer.run(event, callback, feature, scenario)
63
79
  }
64
80
 
65
81
  public getUploadModel(): UploadModel {
@@ -67,7 +83,7 @@ class AuxTA extends FunctionHelper {
67
83
  }
68
84
  }
69
85
 
70
- export const StepStatus = StepStatusEnum;
86
+ export const StepStatus = StatusOfStep;
71
87
 
72
88
  const auxta: AuxTA = new AuxTA();
73
89
 
@@ -16,6 +16,15 @@ export function setupConfig(jsonConfig: any) {
16
16
  if (!jsonConfig.suitesList) throw new Error("suitesList");
17
17
  config.suitesList = jsonConfig.suitesList;
18
18
  if (jsonConfig.timeout) config.timeout = jsonConfig.timeout;
19
+ if (jsonConfig.screenWidth) config.screenWidth = jsonConfig.screenWidth;
20
+ if (jsonConfig.screenHeight) config.screenHeight = jsonConfig.screenHeight;
21
+ return config;
22
+ }
23
+
24
+ export function setupOverrideConfig(overrideConfig: any){
25
+ if (overrideConfig.baseURL) config.baseURL = overrideConfig.baseURL;
26
+ if (overrideConfig.digitalProduct) config.digitalProduct = overrideConfig.digitalProduct;
27
+ return config;
19
28
  }
20
29
 
21
30
  export let config = {
@@ -26,6 +35,8 @@ export let config = {
26
35
  netlifyPath: "",
27
36
  digitalProduct: "",
28
37
  token: "",
38
+ screenWidth: 1920,
39
+ screenHeight: 1080,
29
40
  timeout: 10000,
30
41
  suitesList: [],
31
42
  auxtaCredentials: {
@@ -1,7 +1,7 @@
1
- export enum StepStatusEnum {
1
+ export enum StatusOfStep {
2
2
  PASSED = 'passed',
3
3
  FAILED = 'failed',
4
4
  SKIPPED = 'skipped',
5
5
  SUGGESTION = 'suggestion',
6
6
  }
7
- export default StepStatusEnum;
7
+ export default StatusOfStep;
@@ -9,10 +9,10 @@ import {
9
9
  uploadScenario
10
10
  } from '../services/report.service';
11
11
  import { startSuite } from '../utilities/start-suite.helper';
12
- import { StepStatusEnum } from "../enums/step-status.enum";
12
+ import { StatusOfStep } from "../enums/status-of.step";
13
13
  import { UploadModel } from "../models/upload.model";
14
14
 
15
- export async function AfterEach(body: any, featureName: string, scenarioName: string, statusCode: number, screenshotBuffer: Buffer, errMessage?: string) {
15
+ export async function onTestEnd(body: any, featureName: string, scenarioName: string, statusCode: number, screenshotBuffer: Buffer, errMessage?: object) {
16
16
  let isFinal: boolean = false;
17
17
  if (process.env.ENVIRONMENT == "LIVE") {
18
18
  console.log('asc ' + errMessage);
@@ -29,10 +29,10 @@ export async function AfterEach(body: any, featureName: string, scenarioName: st
29
29
  scenariosCount: featureRes.scenariosCount
30
30
  }
31
31
  const stepCounts: Steps = {
32
- failedSteps: log.getStatusCount(StepStatusEnum.FAILED),
33
- passedSteps: log.getStatusCount(StepStatusEnum.PASSED),
34
- skippedSteps: log.getStatusCount(StepStatusEnum.SKIPPED),
35
- suggestedSteps: log.getStatusCount(StepStatusEnum.SUGGESTION)
32
+ failedSteps: log.getStatusCount(StatusOfStep.FAILED),
33
+ passedSteps: log.getStatusCount(StatusOfStep.PASSED),
34
+ skippedSteps: log.getStatusCount(StatusOfStep.SKIPPED),
35
+ suggestedSteps: log.getStatusCount(StatusOfStep.SUGGESTION)
36
36
  }
37
37
  isFinal = (!(body.nextSuites && body.nextSuites.length > 0));
38
38
  await updateReport(body.reportId, feature, stepCounts, isFinal);
@@ -42,20 +42,15 @@ export async function AfterEach(body: any, featureName: string, scenarioName: st
42
42
  console.log(error)
43
43
  }
44
44
  }
45
- if (isFinal) await AfterComplete(body.reportId, body.endEmail, body);
46
- else if (body && body.nextSuites && body.nextSuites.length > 0)
45
+ if (isFinal) await afterComplete(body.reportId, body);
46
+ else if (body && body.nextSuites && body.nextSuites[0])
47
47
  try {
48
48
  await startSuite(body.nextSuites, body.reportId);
49
49
  } catch {
50
50
  }
51
51
  }
52
52
 
53
- export async function AfterComplete(reportId: string, endEmail: string, body: UploadModel) {
54
- if (process.env.ENVIRONMENT == "LIVE") {
53
+ export async function afterComplete(reportId: string, body: UploadModel) {
54
+ if (process.env.ENVIRONMENT == "LIVE")
55
55
  await postNotifications(reportId, body);
56
- }
57
- }
58
-
59
- export function sleep(ms: number) {
60
- return new Promise(resolve => setTimeout(resolve, ms));
61
56
  }
@@ -2,10 +2,10 @@
2
2
  export class UploadModel {
3
3
  private _reportId: string;
4
4
  private _nextSuites: [];
5
- private readonly _digitalProduct: string;
6
- private readonly _baseUrl: string;
5
+ private _digitalProduct: string;
6
+ private _baseUrl: string;
7
7
  private readonly _organization: string;
8
- private readonly _environment: string;
8
+ private _environment: string;
9
9
 
10
10
  constructor(org: string, baseUrl: string, digitalProduct: string) {
11
11
  this._reportId = '';
@@ -36,15 +36,27 @@ export class UploadModel {
36
36
  return this._digitalProduct;
37
37
  }
38
38
 
39
- get baseUrl(): string {
40
- return this._baseUrl;
39
+ set digitalProduct(value: string) {
40
+ this._digitalProduct = value;
41
41
  }
42
42
 
43
43
  get organization(): string {
44
44
  return this._organization;
45
45
  }
46
46
 
47
+ get baseUrl(): string {
48
+ return this._baseUrl;
49
+ }
50
+
51
+ set baseUrl(value: string) {
52
+ this._baseUrl = value;
53
+ }
54
+
47
55
  get environment(): string {
48
56
  return this._environment;
49
57
  }
58
+
59
+ set environment(value: string) {
60
+ this._environment = value;
61
+ }
50
62
  }
@@ -1,10 +1,10 @@
1
- import { StepStatusEnum } from "../enums/step-status.enum";
1
+ import { StatusOfStep } from "../enums/status-of.step";
2
2
 
3
3
  export interface Step {
4
4
  keyword: string,
5
5
  name: string,
6
6
  result: {
7
- status: StepStatusEnum,
7
+ status: StatusOfStep,
8
8
  duration: number
9
9
  }
10
10
  }
@@ -13,17 +13,17 @@ export class LogSteps {
13
13
  private stepLog: Step[] = [];
14
14
  private lastStepTime = new Date().getTime();
15
15
  public statusCounter = {
16
- [StepStatusEnum.PASSED]: 0,
17
- [StepStatusEnum.FAILED]: 0,
18
- [StepStatusEnum.SKIPPED]: 0,
19
- [StepStatusEnum.SUGGESTION]: 0,
16
+ [StatusOfStep.PASSED]: 0,
17
+ [StatusOfStep.FAILED]: 0,
18
+ [StatusOfStep.SKIPPED]: 0,
19
+ [StatusOfStep.SUGGESTION]: 0,
20
20
  }
21
21
 
22
22
  public addSuggestion(text: string) {
23
- this.statusCounter[StepStatusEnum.SUGGESTION]++;
23
+ this.statusCounter[StatusOfStep.SUGGESTION]++;
24
24
  this.stepLog.push({
25
25
  keyword: 'Suggestion', name: text, result:
26
- {status: StepStatusEnum.SUGGESTION, duration: 0}
26
+ {status: StatusOfStep.SUGGESTION, duration: 0}
27
27
  });
28
28
  }
29
29
 
@@ -31,7 +31,7 @@ export class LogSteps {
31
31
  this.stepLog = [];
32
32
  }
33
33
 
34
- public push(keyword: string, name: string, status: StepStatusEnum) {
34
+ public push(keyword: string, name: string, status: StatusOfStep) {
35
35
  console.log(`System log -- status: ${status} -- : ${name} `);
36
36
  this.statusCounter[status]++;
37
37
  const currentStep = new Date().getTime();
@@ -43,7 +43,7 @@ export class LogSteps {
43
43
  return this.stepLog;
44
44
  }
45
45
 
46
- public getStatusCount(status: StepStatusEnum): number {
46
+ public getStatusCount(status: StatusOfStep): number {
47
47
  return this.statusCounter[status];
48
48
  }
49
49
  }
@@ -66,7 +66,7 @@ export async function createEmptyReport(body: any): Promise<string> {
66
66
  )).data.reportId;
67
67
  }
68
68
 
69
- export async function uploadScenario(stepLog: Step[], scenarioName: string, screenshot?: Buffer, errMessage?: string) {
69
+ export async function uploadScenario(stepLog: Step[], scenarioName: string, screenshot?: Buffer, errMessage?: object) {
70
70
  let scenarios = [];
71
71
  let token = await auth();
72
72
  let lastStep = stepLog[stepLog.length - 1];
@@ -3,9 +3,8 @@ import { config } from "../configs/config";
3
3
 
4
4
  export function startSuite(suites: string[], reportId?: string) {
5
5
  console.log('Starting next suite: ' + suites[0]);
6
- console.log(suites,reportId);
7
6
  return axios.post(
8
- `${config.netlifyPath}.netlify/functions/${suites.shift()}`,
7
+ `${config.netlifyPath}.netlify/functions/${suites.shift()}?token=${config.token}`,
9
8
  { nextSuites: suites, reportId: reportId}
10
9
  );
11
10
  }
@@ -1,12 +1,12 @@
1
1
  import log from "../../auxta/services/log.service";
2
2
  import puppeteer from "../../puppeteer/puppeteer";
3
- import { StepStatusEnum } from "../../auxta/enums/step-status.enum";
3
+ import { StatusOfStep } from "../../auxta/enums/status-of.step";
4
4
  import { config } from "../../auxta/configs/config";
5
5
 
6
6
  export class FunctionHelper {
7
7
  public readonly defaultTimeout: number = config.timeout;
8
8
 
9
- public log(keyword: string, name: string, status: StepStatusEnum){
9
+ public log(keyword: string, name: string, status: StatusOfStep){
10
10
  log.push(keyword, name, status)
11
11
  }
12
12
 
@@ -25,44 +25,51 @@ export class FunctionHelper {
25
25
 
26
26
  const message = `I click on the ${text} ${selector}`;
27
27
  if (linkHandlers) {
28
- log.push('Then', message, StepStatusEnum.PASSED);
28
+ log.push('Then', message, StatusOfStep.PASSED);
29
29
  await linkHandlers.click();
30
30
  } else {
31
- log.push('Then', message, StepStatusEnum.FAILED);
31
+ log.push('Then', message, StatusOfStep.FAILED);
32
32
  throw new Error(`Link not found: ${text}`);
33
33
  }
34
34
  }
35
35
 
36
- public async waitForSelectorWithText(selector: string, text: string) {
37
- const linkHandlers = await puppeteer.defaultPage.$x(`//${selector}[. = ${this.getEscapedText(text)}]`);
36
+ public async waitForSelectorWithText(selector: string, text: string, page = puppeteer.defaultPage) {
37
+ const linkHandlers = await page.$x(`//${selector}[. = ${this.getEscapedText(text)}]`);
38
38
  const message = `I check for ${text}`;
39
39
  if (linkHandlers.length > 0) {
40
- log.push('And', message, StepStatusEnum.PASSED);
40
+ log.push('And', message, StatusOfStep.PASSED);
41
41
  return true;
42
42
  } else {
43
- log.push('And', message, StepStatusEnum.FAILED);
43
+ log.push('And', message, StatusOfStep.FAILED);
44
44
  throw new Error(`Link not found: ${text}`);
45
45
  }
46
46
  }
47
47
 
48
- public async goto(page: string) {
49
- await puppeteer.defaultPage.goto(page);
50
- log.push('Then', `I go to the ${page} page`, StepStatusEnum.PASSED);
48
+ public async goto(url: string, page = puppeteer.defaultPage) {
49
+ await page.goto(url);
50
+ log.push('Then', `I go to the ${url} page`, StatusOfStep.PASSED);
51
51
  }
52
52
 
53
- public async type(field: string, value: string) {
54
- await puppeteer.defaultPage.type(field, value);
55
- let elementName = await puppeteer.defaultPage.$eval(field, (e) => e.textContent);
53
+ public async type(field: string, value: string, page = puppeteer.defaultPage) {
54
+ await page.type(field, value);
55
+ let elementName = await page.$eval(field, (e) => e.textContent);
56
56
  if (!elementName || elementName === ' ') elementName = field;
57
- log.push('Then', `I type '${value}' into the ${elementName} field`, StepStatusEnum.PASSED);
57
+ log.push('Then', `I type '${value}' into the ${elementName} field`, StatusOfStep.PASSED);
58
58
  }
59
59
 
60
- public async waitForNetwork() {
61
- await puppeteer.defaultPage.waitForNetworkIdle();
60
+ public async waitForNetwork(page = puppeteer.defaultPage) {
61
+ let message = 'I wait for the page to load'
62
+ try{
63
+ await page.waitForNetworkIdle();
64
+ log.push('Then', message, StatusOfStep.PASSED);
65
+ } catch (e){
66
+ log.push('Then', message, StatusOfStep.FAILED);
67
+ throw new Error(message)
68
+ }
62
69
  }
63
70
 
64
- public async timeout(timeout = this.defaultTimeout) {
65
- await puppeteer.defaultPage.waitForTimeout(timeout);
71
+ public async timeout(timeout = this.defaultTimeout, page = puppeteer.defaultPage) {
72
+ await page.waitForTimeout(timeout);
66
73
  }
67
74
 
68
75
  /**
@@ -83,10 +90,10 @@ export class FunctionHelper {
83
90
  timeout: time
84
91
  });
85
92
  } catch (e){
86
- log.push('And', message, StepStatusEnum.FAILED);
93
+ log.push('And', message, StatusOfStep.FAILED);
87
94
  throw new Error(message)
88
95
  }
89
- log.push('And', message, StepStatusEnum.PASSED);
96
+ log.push('And', message, StatusOfStep.PASSED);
90
97
  }
91
98
 
92
99
  public async click(className: string, page = puppeteer.defaultPage) {
@@ -94,17 +101,17 @@ export class FunctionHelper {
94
101
  let elementName = await puppeteer.defaultPage.$eval(className, (e) => e.textContent);
95
102
  if (!elementName || elementName === ' ') elementName = className;
96
103
  await page.click(className);
97
- log.push('Then', `I click on ${elementName}`, StepStatusEnum.PASSED);
104
+ log.push('Then', `I click on ${elementName}`, StatusOfStep.PASSED);
98
105
  }
99
106
 
100
107
  public async urlContains(selector: string) {
101
108
  const url = puppeteer.defaultPage.url();
102
109
  let message = `I am on the ${selector} page`
103
110
  if (!url.includes(selector)) {
104
- log.push('And', message, StepStatusEnum.FAILED);
111
+ log.push('And', message, StatusOfStep.FAILED);
105
112
  throw new Error(`I am not at the ${selector} page`)
106
113
  }
107
- log.push('And', message, StepStatusEnum.PASSED);
114
+ log.push('And', message, StatusOfStep.PASSED);
108
115
  }
109
116
 
110
117
  }
@@ -1,9 +1,9 @@
1
1
  import chromium from 'chrome-aws-lambda';
2
2
  import log from "../auxta/services/log.service";
3
3
  import { captureScreenshot } from "../auxta/utilities/screenshot.helper";
4
- import { AfterEach } from "../auxta/hooks/report.hook";
4
+ import { onTestEnd } from "../auxta/hooks/report.hook";
5
5
  import auxta from "../AuxTA";
6
- import { StepStatusEnum } from "../auxta/enums/step-status.enum";
6
+ import { StatusOfStep } from "../auxta/enums/status-of.step";
7
7
  import { UploadModel } from "../auxta/models/upload.model";
8
8
  import puppeteer_core from 'puppeteer-core';
9
9
  import { config } from "./../auxta/configs/config";
@@ -14,21 +14,27 @@ export class Puppeteer {
14
14
  private browser!: puppeteer_core.Browser;
15
15
 
16
16
  public async startBrowser() {
17
+ let args = [
18
+ '--start-maximized',
19
+ '--no-sandbox',
20
+ '--disable-setuid-sandbox',
21
+ '--disable-dev-shm-usage',
22
+ '--single-process'
23
+ ];
24
+ if (process.env.ENVIRONMENT != 'LOCAL')
25
+ args.push(`--window-size=${config.screenWidth},${config.screenHeight}`)
17
26
  this.browser = await chromium.puppeteer.launch({
18
27
  executablePath: process.env.NODE_ENV !== 'production' ? undefined : await chromium.executablePath,
19
- args: [
20
- '--start-maximized',
21
- '--no-sandbox',
22
- '--disable-setuid-sandbox',
23
- '--disable-dev-shm-usage',
24
- '--single-process'
25
- ],
26
- defaultViewport: null,
27
- // Return back to headless for commit
28
+ args,
29
+ defaultViewport: process.env.ENVIRONMENT == 'LOCAL' ? null : {
30
+ width: config.screenWidth,
31
+ height: config.screenHeight
32
+ },
33
+ // Return back to headless for netlify
28
34
  headless: process.env.ENVIRONMENT == 'LOCAL' ? false : chromium.headless
29
35
  });
30
36
  this.defaultPage = (await this.browser.pages())[0];
31
- await this.defaultPage.goto(config.baseURL)
37
+ await this.defaultPage.goto(config.baseURL, {waitUntil: 'networkidle0'})
32
38
  await this.defaultPage.waitForNetworkIdle();
33
39
  }
34
40
 
@@ -47,22 +53,36 @@ export class Puppeteer {
47
53
  let errMessage: string | undefined;
48
54
  let statusCode: number = 200;
49
55
 
56
+ let consoleStack: any[] = [];
50
57
  try {
51
- await log.push('When', `Starting puppeteer process`, StepStatusEnum.PASSED);
58
+ await log.push('When', `Starting puppeteer process`, StatusOfStep.PASSED);
52
59
  await this.startBrowser()
60
+ this.defaultPage.on('console', message =>
61
+ consoleStack.push(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`))
62
+ .on('pageerror', ({message}) => consoleStack.push(message))
63
+ .on('response', response =>
64
+ consoleStack.push(`${response.status()} ${response.url()}`))
65
+ .on('requestfailed', request =>
66
+ consoleStack.push(`${request.failure().errorText} ${request.url()}`))
53
67
  await callback(event)
54
68
  screenshotBuffer = await captureScreenshot();
55
- await log.push('When', `Finished puppeteer process`, StepStatusEnum.PASSED);
69
+ await log.push('When', `Finished puppeteer process`, StatusOfStep.PASSED);
56
70
  } catch (err: any) {
57
71
  console.log(`Error ${err}`);
58
72
  errMessage = err;
59
73
  statusCode = 500;
60
74
  screenshotBuffer = await captureScreenshot();
61
- await log.push('When', `Finished puppeteer process`, StepStatusEnum.FAILED);
75
+ await log.push('When', `Finished puppeteer process`, StatusOfStep.FAILED);
62
76
  }
77
+ let url = this.defaultPage.url();
63
78
  if (close) await this.close();
64
79
 
65
- await AfterEach(uploadModel, featureName, scenarioName, statusCode, screenshotBuffer, errMessage);
80
+ await onTestEnd(uploadModel, featureName, scenarioName, statusCode, screenshotBuffer, !errMessage ? undefined : {
81
+ currentPageUrl: url,
82
+ console: consoleStack,
83
+ error: errMessage
84
+ });
85
+ log.clear();
66
86
  }
67
87
 
68
88
  private static setupHeader(event: any, uploadModel: UploadModel) {