@auxcode/auxta 0.1.3 → 0.1.7

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auxcode/auxta",
3
- "version": "0.1.3",
3
+ "version": "0.1.7",
4
4
  "description": "",
5
5
  "main": "src/AuxTA.ts",
6
6
  "scripts": {
package/src/AuxTA.ts CHANGED
@@ -1,46 +1,68 @@
1
1
  import puppeteer, { Puppeteer } from "./puppeteer/puppeteer";
2
2
  import { FunctionHelper } from "./macros/helpers/code.helper";
3
- import f from "./macros/helpers/code.helper";
4
- import run from "./auxta/run";
5
- import { Log } from "./auxta/services/log.service";
6
- import defaultLog from "./auxta/services/log.service";
7
3
  import path from "path";
8
4
  import fs from "fs";
9
- import { StepStatusEnum } from "./auxta/enums/step-status.enum";
5
+ import StepStatusEnum from "./auxta/enums/step-status.enum";
10
6
  import { UploadModel } from "./auxta/models/upload.model";
11
7
  import * as dotenv from "dotenv";
12
- import { setupConfig } from "./auxta/configs/config";
8
+ import { config, setupConfig } from "./auxta/configs/config";
9
+ import { startSuite } from "./auxta/utilities/start-suite.helper";
10
+ import { createEmptyReport } from "./auxta/services/report.service";
13
11
 
14
12
  dotenv.config();
15
13
 
16
- class AuxTA {
14
+ class AuxTA extends FunctionHelper {
17
15
  public puppeteer: Puppeteer = puppeteer;
18
- public func: FunctionHelper = f;
19
- public run: Function = run;
20
- public logger: Log.LogSteps = defaultLog;
21
16
 
22
17
  private readonly uploadModel: UploadModel;
23
18
 
24
19
  constructor() {
20
+ super();
25
21
  let file;
26
22
  try {
27
23
  //todo find a better way to load the file
28
- file = path.join(__dirname, "../../../../../../", "suitesList.json");
24
+ let currentDir = "../"
25
+ while (true) {
26
+ file = path.join(__dirname, currentDir, "auxta.json");
27
+ try {
28
+ fs.accessSync(file, fs.constants.R_OK | fs.constants.W_OK)
29
+ break;
30
+ } catch {
31
+ currentDir += "../"
32
+ if (currentDir.length >= 30) {
33
+ process.exit(1);
34
+ return;
35
+ }
36
+ }
37
+ }
29
38
  const jsonConfig = JSON.parse(fs.readFileSync(file).toString());
30
39
  try {
31
40
  setupConfig(jsonConfig)
32
- } catch (e) {
33
- if (e instanceof Error) console.log("Missing field in suitesList.json:", e.message)
34
- process.exit(1);
41
+ } catch (e: any) {
42
+ console.log("Missing field in auxta.json:", e.message)
35
43
  }
36
44
  this.uploadModel = new UploadModel(jsonConfig.organization, jsonConfig.baseURL, jsonConfig.digitalProduct);
37
- } catch (e) {
45
+ } catch (e: any) {
38
46
  console.log("Missing or corrupted config: suitesList.json. Searching in location:", file)
39
47
  console.log(e);
40
48
  process.exit(1);
41
49
  }
42
50
  }
43
51
 
52
+ public async run(event: any) {
53
+ const model = this.uploadModel;
54
+ let token: string = event.queryStringParameters.token;
55
+ let reportId: string | undefined = event.queryStringParameters.reportId;
56
+ if (token !== config.token) return {statusCode: 401, message: 'Unauthorized'}
57
+ const suites = config.suitesList.slice(0);
58
+ await startSuite(suites, reportId || await createEmptyReport(model));
59
+ return {statusCode: 204}
60
+ }
61
+
62
+ public startBrowser(event: any, callback: any, feature: string, scenario: string) {
63
+ this.puppeteer.run(event, callback, feature, scenario)
64
+ }
65
+
44
66
  public getUploadModel(): UploadModel {
45
67
  return this.uploadModel;
46
68
  }
@@ -50,11 +72,4 @@ export const StepStatus = StepStatusEnum;
50
72
 
51
73
  const auxta: AuxTA = new AuxTA();
52
74
 
53
- export const auxtaLogger = auxta.logger;
54
- export const auxtaPuppeteer = auxta.puppeteer;
55
- export const auxtaSuggest = auxta.logger.addSuggestion;
56
- export const auxtaLog = auxta.logger.push;
57
- export const auxtaRun = auxta.run;
58
- export const auxtaFunc = auxta.func;
59
-
60
75
  export default auxta;
@@ -4,3 +4,4 @@ export enum StepStatusEnum {
4
4
  SKIPPED = 'skipped',
5
5
  SUGGESTION = 'suggestion',
6
6
  }
7
+ export default StepStatusEnum;
@@ -10,7 +10,7 @@ import {
10
10
  } from '../services/report.service';
11
11
  import { startSuite } from '../utilities/start-suite.helper';
12
12
  import { StepStatusEnum } from "../enums/step-status.enum";
13
- import UploadModel from "../models/upload.model";
13
+ import { UploadModel } from "../models/upload.model";
14
14
 
15
15
  export async function AfterEach(body: any, featureName: string, scenarioName: string, statusCode: number, screenshotBuffer: Buffer, errMessage?: string) {
16
16
  let isFinal: boolean = false;
@@ -48,5 +48,3 @@ export class UploadModel {
48
48
  return this._environment;
49
49
  }
50
50
  }
51
-
52
- export default UploadModel;
@@ -1,46 +1,52 @@
1
1
  import { StepStatusEnum } from "../enums/step-status.enum";
2
2
 
3
- export namespace Log {
4
- export interface Step {
5
- keyword: string,
6
- name: string,
7
- result: {
8
- status: StepStatusEnum,
9
- duration: number
10
- }
3
+ export interface Step {
4
+ keyword: string,
5
+ name: string,
6
+ result: {
7
+ status: StepStatusEnum,
8
+ duration: number
9
+ }
10
+ }
11
+
12
+ export class LogSteps {
13
+ private stepLog: Step[] = [];
14
+ private lastStepTime = new Date().getTime();
15
+ public statusCounter = {
16
+ [StepStatusEnum.PASSED]: 0,
17
+ [StepStatusEnum.FAILED]: 0,
18
+ [StepStatusEnum.SKIPPED]: 0,
19
+ [StepStatusEnum.SUGGESTION]: 0,
20
+ }
21
+
22
+ public addSuggestion(text: string) {
23
+ this.statusCounter[StepStatusEnum.SUGGESTION]++;
24
+ this.stepLog.push({
25
+ keyword: 'Suggestion', name: text, result:
26
+ {status: StepStatusEnum.SUGGESTION, duration: 0}
27
+ });
28
+ }
29
+
30
+ public clear() {
31
+ this.stepLog = [];
32
+ }
33
+
34
+ public push(keyword: string, name: string, status: StepStatusEnum) {
35
+ console.log(`System log -- status: ${status} -- : ${name} `);
36
+ this.statusCounter[status]++;
37
+ const currentStep = new Date().getTime();
38
+ this.stepLog.push({keyword, name, result: {status, duration: currentStep - this.lastStepTime}});
39
+ this.lastStepTime = currentStep;
40
+ }
41
+
42
+ public returnScenarioReport() {
43
+ return this.stepLog;
11
44
  }
12
45
 
13
- export class LogSteps {
14
- private stepLog: Log.Step[] = [];
15
- private statusCounter = {
16
- [StepStatusEnum.PASSED]: 0,
17
- [StepStatusEnum.FAILED]: 0,
18
- [StepStatusEnum.SKIPPED]: 0,
19
- [StepStatusEnum.SUGGESTION]: 0,
20
- }
21
-
22
- public addSuggestion(text: string) {
23
- this.push('Suggest', text, StepStatusEnum.SUGGESTION, 1000000);
24
- }
25
-
26
- public clear() {
27
- this.stepLog = [];
28
- }
29
-
30
- public push(keyword: string, name: string, status: StepStatusEnum, duration: number) {
31
- console.log(`System log -- status: ${status} -- : ${name} `);
32
- this.statusCounter[status] = this.statusCounter[status] + 1;
33
- this.stepLog.push({ keyword: keyword, name: name, result: { status: status, duration: duration } });
34
- }
35
-
36
- public returnScenarioReport() {
37
- return this.stepLog;
38
- }
39
-
40
- public getStatusCount(status: StepStatusEnum): number{
41
- return this.statusCounter[status];
42
- }
46
+ public getStatusCount(status: StepStatusEnum): number {
47
+ return this.statusCounter[status];
43
48
  }
44
49
  }
45
50
 
46
- export default new Log.LogSteps();
51
+ const log = new LogSteps();
52
+ export default log;
@@ -1,7 +1,7 @@
1
1
  import axios from "axios";
2
- import { Log } from "./log.service";
2
+ import { Step } from "./log.service";
3
3
  import { config } from "../configs/config";
4
- import UploadModel from "../models/upload.model";
4
+ import { UploadModel } from "../models/upload.model";
5
5
 
6
6
  export interface Feature {
7
7
  featureId: string,
@@ -62,7 +62,7 @@ export async function createEmptyReport(body: any): Promise<string> {
62
62
  )).data.reportId;
63
63
  }
64
64
 
65
- export async function uploadScenario(stepLog: Log.Step[], scenarioName: string, screenshot?: Buffer, errMessage?: string) {
65
+ export async function uploadScenario(stepLog: Step[], scenarioName: string, screenshot?: Buffer, errMessage?: string) {
66
66
  let scenarios = [];
67
67
  let token = await auth();
68
68
  let lastStep = stepLog[stepLog.length - 1];
@@ -1,7 +1,8 @@
1
- import { auxtaPuppeteer } from "../../AuxTA";
1
+ import puppeteer from "../../puppeteer/puppeteer";
2
2
 
3
3
  export async function captureScreenshot() {
4
- const pages = await auxtaPuppeteer.defaultPage.browser().pages();
4
+ const pages = await puppeteer.defaultPage.browser().pages();
5
+ if (!pages.length) throw `Browser is closed`;
5
6
  const lastPage = pages[pages.length - 1];
6
7
 
7
8
  const screenshotBuffer = await lastPage.screenshot({
@@ -9,7 +10,7 @@ export async function captureScreenshot() {
9
10
  encoding: 'binary'
10
11
  }
11
12
  );
12
- if (Buffer.isBuffer(screenshotBuffer))
13
+ if (Buffer.isBuffer(screenshotBuffer))
13
14
  return screenshotBuffer;
14
15
  else throw `Failed to capture buffer screenshot`;
15
16
  }
@@ -3,36 +3,64 @@ import puppeteer from "../../puppeteer/puppeteer";
3
3
  import { StepStatusEnum } from "../../auxta/enums/step-status.enum";
4
4
 
5
5
  export class FunctionHelper {
6
- public readonly timeout: number = Number(process.env.AUXTA_TIMEOUT);
6
+ public readonly defaultTimeout: number = Number(process.env.AUXTA_TIMEOUT);
7
7
 
8
- public async clickByText(selector: string, text: string, page = puppeteer.defaultPage) {
9
- await page.waitForTimeout(this.timeout);
8
+ public log(keyword: string, name: string, status: StepStatusEnum){
9
+ log.push(keyword, name, status)
10
+ }
11
+
12
+ public suggest(name: string){
13
+ log.addSuggestion(name)
14
+ }
15
+
16
+ private getEscapedText(text: string){
10
17
  const splitedQuotes = text.replace(/'/g, `', "'", '`)
11
- const escapedText = `concat('${splitedQuotes}', '')`;
12
- const [linkHandlers] = await page.$x(`//${selector}[. = ${escapedText}]`);
18
+ return `concat('${splitedQuotes}', '')`;
19
+ }
20
+
21
+ public async clickByText(selector: string, text: string, page = puppeteer.defaultPage) {
22
+ await page.waitForTimeout(this.defaultTimeout);
23
+ const [linkHandlers] = await page.$x(`//${selector}[. = ${this.getEscapedText(text)}]`);
13
24
 
14
25
  if (linkHandlers) {
15
- log.push('And', `I click ${selector} with text ${text}`, StepStatusEnum.PASSED, 1000000);
26
+ log.push('And', `I click on the ${text} ${selector}`, StepStatusEnum.PASSED);
16
27
  await linkHandlers.click();
17
28
  } else {
18
- log.push('And', `I click ${selector} with text ${text}`, StepStatusEnum.FAILED, 1000000);
29
+ log.push('And', `I click on the ${text} ${selector}`, StepStatusEnum.FAILED);
19
30
  throw new Error(`Link not found: ${text}`);
20
31
  }
21
32
  }
22
33
 
23
34
  public async waitForSelectorWithText(selector: string, text: string) {
24
- const splitedQuotes = text.replace(/'/g, `', "'", '`)
25
- const escapedText = `concat('${splitedQuotes}', '')`;
26
- const linkHandlers = await puppeteer.defaultPage.$x(`//${selector}[. = ${escapedText}]`);
35
+ const linkHandlers = await puppeteer.defaultPage.$x(`//${selector}[. = ${this.getEscapedText(text)}]`);
27
36
  if (linkHandlers.length > 0) {
28
- log.push('And', `I checked for ${text} and found it.`, StepStatusEnum.PASSED, 1000000);
37
+ log.push('And', `I checked for ${text} and found it.`, StepStatusEnum.PASSED);
29
38
  return true;
30
39
  } else {
31
- log.push('And', `I checked for ${text} and found it.`, StepStatusEnum.FAILED, 1000000);
40
+ log.push('And', `I checked for ${text} and found it.`, StepStatusEnum.FAILED);
32
41
  throw new Error(`Link not found: ${text}`);
33
42
  }
34
43
  }
35
44
 
45
+ public async goto(page: string) {
46
+ await puppeteer.defaultPage.goto(page);
47
+ log.push('And', `I go to the ${page} page`, StepStatusEnum.PASSED);
48
+ }
49
+
50
+ public async type(field: string, value: string) {
51
+ await puppeteer.defaultPage.type(field, value);
52
+ const elementName = await puppeteer.defaultPage.$eval(field, (e) => e.textContent);
53
+ log.push('And', `I type '${value}' into the ${elementName} field`, StepStatusEnum.PASSED);
54
+ }
55
+
56
+ public async waitForNetwork() {
57
+ await puppeteer.defaultPage.waitForNetworkIdle();
58
+ }
59
+
60
+ public async timeout(timeout = this.defaultTimeout) {
61
+ await puppeteer.defaultPage.waitForTimeout(timeout);
62
+ }
63
+
36
64
  /**
37
65
  * Waiting for selector with timeout 60000
38
66
  *
@@ -43,7 +71,7 @@ export class FunctionHelper {
43
71
  * @param page
44
72
  */
45
73
 
46
- public async waitForSelector(option: string, selector: string, time: number = this.timeout, page = puppeteer.defaultPage) {
74
+ public async waitForSelector(option: string, selector: string, time: number = this.defaultTimeout, page = puppeteer.defaultPage) {
47
75
  await page.waitForSelector(selector, {
48
76
  [option]: true,
49
77
  timeout: time
@@ -51,17 +79,19 @@ export class FunctionHelper {
51
79
  }
52
80
 
53
81
  public async click(className: string, page = puppeteer.defaultPage) {
54
- await page.waitForTimeout(this.timeout);
82
+ await page.waitForTimeout(this.defaultTimeout);
55
83
  await page.click(className);
84
+ const elementName = await puppeteer.defaultPage.$eval(className, (e) => e.textContent);
85
+ log.push('Then', `I click on ${elementName}`, StepStatusEnum.PASSED);
56
86
  }
57
87
 
58
88
  public async urlContains(selector: string) {
59
89
  const url = puppeteer.defaultPage.url();
60
90
  if (!url.includes(selector)) {
61
- await log.push('And', `I am on the ${selector} page`, StepStatusEnum.FAILED, 1000000);
91
+ log.push('And', `I am on the ${selector} page`, StepStatusEnum.FAILED);
62
92
  throw new Error(`I am not at the ${selector} page`)
63
93
  }
64
- await log.push('And', `I am on the ${selector} page`, StepStatusEnum.PASSED, 1000000);
94
+ log.push('And', `I am on the ${selector} page`, StepStatusEnum.PASSED);
65
95
  }
66
96
 
67
97
  }
@@ -1,12 +1,13 @@
1
1
  import chromium from 'chrome-aws-lambda';
2
2
  import log from "../auxta/services/log.service";
3
- import { returnImage } from '../auxta/helpers/response.helper';
4
3
  import { captureScreenshot } from "../auxta/utilities/screenshot.helper";
5
4
  import { AfterEach } from "../auxta/hooks/report.hook";
6
5
  import auxta from "../AuxTA";
7
6
  import { StepStatusEnum } from "../auxta/enums/step-status.enum";
8
7
  import { UploadModel } from "../auxta/models/upload.model";
9
8
  import puppeteer_core from 'puppeteer-core';
9
+ import { config } from "./../auxta/configs/config";
10
+
10
11
 
11
12
  export class Puppeteer {
12
13
  public defaultPage!: puppeteer_core.Page;
@@ -22,26 +23,12 @@ export class Puppeteer {
22
23
  '--disable-dev-shm-usage',
23
24
  '--single-process'
24
25
  ],
25
- defaultViewport: chromium.defaultViewport,
26
+ defaultViewport: null,
26
27
  // Return back to headless for commit
27
28
  headless: process.env.ENVIRONMENT == 'LOCAL' ? false : chromium.headless
28
29
  });
29
- this.defaultPage = await this.browser.newPage();
30
- await this.defaultPage.setViewport({
31
- width: 1440,
32
- height: 900
33
- });
34
- }
35
-
36
- public async goto(page: string) {
37
- await this.defaultPage.goto(page);
38
- }
39
-
40
- public async type(field: string, value: string) {
41
- await this.defaultPage.type(field, value);
42
- }
43
-
44
- public async waitForNetwork() {
30
+ this.defaultPage = (await this.browser.pages())[0];
31
+ await this.defaultPage.goto(config.baseURL)
45
32
  await this.defaultPage.waitForNetworkIdle();
46
33
  }
47
34
 
@@ -53,7 +40,7 @@ export class Puppeteer {
53
40
  }
54
41
  }
55
42
 
56
- public async run(event: any, callback: any, FeatureName = 'Test feature', ScenarioName = 'Test scenario', uploadModel?: UploadModel, close?: boolean) {
43
+ public async run(event: any, callback: any, featureName = 'Test feature', scenarioName = 'Test scenario', uploadModel?: UploadModel, close?: boolean) {
57
44
  if (uploadModel === undefined) uploadModel = auxta.getUploadModel();
58
45
  if (close === undefined) close = Puppeteer.setupHeader(event, uploadModel)
59
46
  let screenshotBuffer: Buffer;
@@ -61,23 +48,21 @@ export class Puppeteer {
61
48
  let statusCode: number = 200;
62
49
 
63
50
  try {
64
- await log.push('When', `Starting puppeteer process`, StepStatusEnum.PASSED, 1000000);
51
+ await log.push('When', `Starting puppeteer process`, StepStatusEnum.PASSED);
65
52
  await this.startBrowser()
66
53
  await callback(event)
67
54
  screenshotBuffer = await captureScreenshot();
68
- await log.push('When', `Finished puppeteer process`, StepStatusEnum.PASSED, 1000000);
55
+ await log.push('When', `Finished puppeteer process`, StepStatusEnum.PASSED);
69
56
  } catch (err: any) {
70
- console.log(`This is an error ${err}`);
57
+ console.log(`Error ${err}`);
71
58
  errMessage = err;
72
59
  statusCode = 500;
73
60
  screenshotBuffer = await captureScreenshot();
74
- await log.push('When', `Finished puppeteer process`, StepStatusEnum.FAILED, 1000000);
61
+ await log.push('When', `Finished puppeteer process`, StepStatusEnum.FAILED);
75
62
  }
76
63
  if (close) await this.close();
77
64
 
78
- await AfterEach(uploadModel, FeatureName, ScenarioName, statusCode, screenshotBuffer, errMessage);
79
-
80
- return returnImage(statusCode, screenshotBuffer);
65
+ await AfterEach(uploadModel, featureName, scenarioName, statusCode, screenshotBuffer, errMessage);
81
66
  }
82
67
 
83
68
  private static setupHeader(event: any, uploadModel: UploadModel) {
package/src/auxta/run.ts DELETED
@@ -1,14 +0,0 @@
1
- import { createEmptyReport } from "./services/report.service";
2
- import { startSuite } from "./utilities/start-suite.helper";
3
- import auxta from "../AuxTA";
4
- import { config } from "./configs/config";
5
-
6
- export default async function run(event: any) {
7
- const model = auxta.getUploadModel();
8
- let token: string = event.queryStringParameters.token;
9
- let reportId: string | undefined = event.queryStringParameters.reportId;
10
- if (token !== config.token) return {statusCode: 401, message: 'Unauthorized'}
11
- const suites = config.suitesList.slice(0);
12
- await startSuite(suites, reportId || await createEmptyReport(model));
13
- return {statusCode: 204}
14
- }