@zohodesk/testinglibrary 0.0.1-exp.1

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 ADDED
@@ -0,0 +1,18 @@
1
+ # Testing Framework
2
+
3
+ ## Framework that abstracts the configuration for playwright and Jest
4
+
5
+ - Playwright
6
+ - Jest
7
+
8
+ ## Cli
9
+
10
+ ## Feature Supported
11
+
12
+ ### Run TestCase
13
+
14
+ - npm run test
15
+ ### Generate Report
16
+
17
+ - npm run report
18
+
package/bin/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('../src/lib/cli');
@@ -0,0 +1,16 @@
1
+ const path = require('path');
2
+ const { spawn } = require('child_process');
3
+ const { Logger } = require('../src/utils/logger');
4
+ const getFilePathWithExtension = require('../src/utils/getFilePath');
5
+
6
+ const playwrightPath = path.resolve('node_modules', '.bin', getFilePathWithExtension('playwright'));
7
+ const command = playwrightPath;
8
+ const args = ['install'];
9
+
10
+ Logger.log(Logger.INFO_TYPE, 'Downloading browsers for running tests');
11
+
12
+ const childProcess = spawn(command, args, { stdio: 'inherit' });
13
+
14
+ childProcess.on('error', (error) => {
15
+ Logger.log(Logger.FAILURE_TYPE, error);
16
+ });
package/jest.config.js ADDED
@@ -0,0 +1,64 @@
1
+ const path = require('path');
2
+ const { existsSync } = require('fs');
3
+ const appPath = process.cwd();
4
+
5
+ const appGlobals = path.resolve(appPath, '__testUtils__', 'globals.js');
6
+
7
+ module.exports = {
8
+ rootDir: process.cwd(),
9
+ testEnvironment: 'jsdom',
10
+
11
+ setupFilesAfterEnv: [
12
+ existsSync(appGlobals) && appGlobals,
13
+ path.resolve(__dirname, 'src', 'core', 'jest', 'setup', 'index.js')
14
+ ].filter(Boolean),
15
+
16
+ transform: {
17
+ '^.+\\.(js|jsx)$': path.resolve(
18
+ __dirname,
19
+ 'src',
20
+ 'core',
21
+ 'jest',
22
+ 'preprocessor',
23
+ 'jsPreprocessor.js'
24
+ )
25
+ },
26
+
27
+ modulePathIgnorePatterns: ['/build/'],
28
+
29
+ transformIgnorePatterns: [
30
+ '/node_modules/(?!(@zohodesk)/)'
31
+ ],
32
+
33
+ testPathIgnorePatterns: [
34
+ '/node_modules/',
35
+ '/build/',
36
+ '/uat/'
37
+ ],
38
+
39
+ watchPathIgnorePatterns: [
40
+ '/node_modules/',
41
+ '/build/'
42
+ ],
43
+
44
+ clearMocks: true,
45
+ resetMocks: false,
46
+
47
+ collectCoverage: true,
48
+ collectCoverageFrom: ['src/**/*.js'],
49
+ coverageDirectory: './build/cov',
50
+ coverageReporters: ['lcov', 'json', 'html', 'json-summary', 'text'],
51
+ coverageThreshold: {
52
+ global: {
53
+ branches: 100,
54
+ functions: 100,
55
+ lines: 100,
56
+ statements: 100
57
+ }
58
+ },
59
+ globals: {
60
+ __DEVELOPMENT__: true,
61
+ __DOCS__: false,
62
+ __TEST__: true
63
+ }
64
+ };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@zohodesk/testinglibrary",
3
+ "version": "0.0.1-exp.1",
4
+ "description": "",
5
+ "main": "./src/index.js",
6
+ "scripts": {
7
+ "postinstall": "node bin/postinstall.js",
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "@babel/preset-env": "^7.22.9",
15
+ "@babel/preset-react": "^7.22.5",
16
+ "@playwright/test": "^1.37.1",
17
+ "@testing-library/jest-dom": "^5.11.9",
18
+ "@testing-library/react": "^11.2.7",
19
+ "@testing-library/react-hooks": "^7.0.2",
20
+ "babel-jest": "^29.6.2",
21
+ "babel-plugin-transform-dynamic-import": "^2.1.0",
22
+ "jest": "^29.6.2",
23
+ "jest-environment-jsdom": "^29.6.2",
24
+ "msw": "^1.2.3",
25
+ "react": "16.13.1",
26
+ "react-dom": "16.13.1"
27
+ },
28
+ "bin": {
29
+ "ZDTestingFramework": "./bin/cli.js"
30
+ }
31
+ }
@@ -0,0 +1,112 @@
1
+ // @ts-check
2
+ const { defineConfig, devices } = require('@playwright/test');
3
+ const path = require('path');
4
+ const numCPUs = require('os').cpus().length;
5
+
6
+ /**
7
+ * Read environment variables from file.
8
+ * https://github.com/motdotla/dotenv
9
+ */
10
+ // require('dotenv').config();
11
+
12
+ /**
13
+ * @see https://playwright.dev/docs/test-configuration
14
+ */
15
+ module.exports = defineConfig({
16
+ testDir: path.join(path.resolve(process.cwd()), 'uat'),
17
+ outputDir: path.join(process.cwd(), 'test-results'),
18
+ /* Run tests in files in parallel */
19
+ fullyParallel: true,
20
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
21
+ forbidOnly: !!process.env.CI,
22
+ /* Retry on CI only */
23
+ retries: process.env.CI ? 2 : 0,
24
+ /* Opt out of parallel tests on CI. */
25
+ workers: process.env.CI ? 1 : 1,
26
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
27
+ reporter: [['html', { outputFolder: path.join(process.cwd(), 'playwright-report'), open: "always" }]],
28
+ timeout: 60 * 1000,
29
+ expect: {
30
+ timeout: 5 * 1000,
31
+ },
32
+
33
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
34
+ use: {
35
+ /* Base URL to use in actions like `await page.goto('/')`. */
36
+ //baseURL: process.env.domain,
37
+
38
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
39
+ trace: 'on',
40
+ video: {
41
+ mode: 'on',
42
+ size: { width: 640, height: 480 }
43
+ }
44
+ },
45
+
46
+ /* Configure projects for major browsers */
47
+ projects: [
48
+ { name: 'setup', testMatch: /.*\.setup\.js/ },
49
+ {
50
+ name: 'chromium',
51
+ use: {
52
+ ...devices['Desktop Chrome'],
53
+ storageState: path.resolve(process.cwd(), 'playwright/.auth/user.json')
54
+ },
55
+ dependencies: ['setup'],
56
+ },
57
+
58
+ {
59
+ name: 'firefox',
60
+ timeout: 4 * 60 * 1000,
61
+ expect: {
62
+ timeout: 80 * 1000,
63
+ },
64
+ use: {
65
+ ...devices['Desktop Firefox'],
66
+ storageState: path.resolve(process.cwd(), 'playwright/.auth/user.json')
67
+ },
68
+ dependencies: ['setup'],
69
+ },
70
+
71
+ {
72
+ name: 'webkit',
73
+ timeout: 2 * 60 * 1000,
74
+ expect: {
75
+ timeout: 80 * 1000,
76
+ },
77
+ use: {
78
+ ...devices['Desktop Safari'],
79
+ storageState: path.resolve(process.cwd(), 'playwright/.auth/user.json')
80
+ },
81
+ dependencies: ['setup'],
82
+ },
83
+
84
+ /* Test against mobile viewports. */
85
+ // {
86
+ // name: 'Mobile Chrome',
87
+ // use: { ...devices['Pixel 5'] },
88
+ // },
89
+ // {
90
+ // name: 'Mobile Safari',
91
+ // use: { ...devices['iPhone 12'] },
92
+ // },
93
+
94
+ /* Test against branded browsers. */
95
+ // {
96
+ // name: 'Microsoft Edge',
97
+ // use: { ...devices['Desktop Edge'], channel: 'msedge' },
98
+ // },
99
+ // {
100
+ // name: 'Google Chrome',
101
+ // use: { ...devices['Desktop Chrome'], channel: 'chrome' },
102
+ // },
103
+ ],
104
+
105
+ /* Run your local dev server before starting the tests */
106
+ // webServer: {
107
+ // command: 'npm run start',
108
+ // url: 'http://127.0.0.1:3000',
109
+ // reuseExistingServer: !process.env.CI,
110
+ // },
111
+ });
112
+
@@ -0,0 +1,9 @@
1
+ const babelJest = require('babel-jest');
2
+
3
+ module.exports = babelJest.createTransformer({
4
+ presets: [
5
+ require.resolve('@babel/preset-env'),
6
+ require.resolve('@babel/preset-react')
7
+ ],
8
+ plugins: [require.resolve('babel-plugin-transform-dynamic-import')]
9
+ });
@@ -0,0 +1,45 @@
1
+ // import { run } from 'jest';
2
+
3
+ // function createJestRunner() {
4
+ // let config = require('../configs/jest.config');
5
+
6
+ // let argv = process.argv.slice(2);
7
+
8
+ // argv.push('--config', JSON.stringify(config(folder)), '--no-cache');
9
+ // run(argv);
10
+ // }
11
+
12
+
13
+ // export default createJestRunner;
14
+
15
+ const { spawn } = require('child_process');
16
+ const path = require('path');
17
+ const getFilePathWithExtension = require('../../../utils/getFilePath');
18
+ const { getBinPath } = require('../../../utils/rootPath');
19
+
20
+ const jestPath = path.resolve(getBinPath(), getFilePathWithExtension('jest'));
21
+
22
+ // Command and arguments for npx playwright test
23
+ const command = jestPath;
24
+ const args = ['--config', require.resolve('../../../../jest.config.js')];
25
+
26
+
27
+ function createJestRunner() {
28
+ // Spawn the child process
29
+
30
+ const childProcess = spawn(command, args, { stdio: 'inherit' });
31
+
32
+
33
+ // Handling the 'exit' event of the child process
34
+ // childProcess.on('exit', (code, signal) => {
35
+ // console.log(`Child process exited with code ${code} and signal ${signal}`);
36
+ // });
37
+
38
+ // // Handling any error that occurs while spawning the child process
39
+ // childProcess.on('error', (err) => {
40
+ // console.error(`Error while spawning child process: ${err.message}`);
41
+ // });
42
+ }
43
+
44
+
45
+ module.exports = createJestRunner;
@@ -0,0 +1,165 @@
1
+ //$Id$//
2
+ import TestUtils from 'react-dom/test-utils';
3
+ import { expect } from '@jest/globals'
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import ReactDOM from 'react-dom';
7
+ import '@testing-library/jest-dom/extend-expect';
8
+ // let mockDomain = 'htt' + 'p://zoho.com';
9
+ // const { document } = new JSDOM('').window;
10
+ // global.document = document;
11
+ // global.window = document.defaultView;
12
+ // global.navigator = global.window.navigator;
13
+ // global.localStorage = global.sessionStorage = {
14
+ // getItem(key) {
15
+ // return this[key];
16
+ // },
17
+ // setItem(key, value) {
18
+ // if (value.length > 100) {
19
+ // throw new Error('Data size is too exceeded');
20
+ // }
21
+ // this[key] = value;
22
+ // },
23
+ // removeItem(key) {
24
+ // delete this[key];
25
+ // },
26
+ // clear() {
27
+ // let keys = ['getItem', 'setItem', 'removeItem', 'clear'];
28
+ // for (let key in this) {
29
+ // if (keys.indexOf(key) === -1) {
30
+ // delete this[key];
31
+ // }
32
+ // }
33
+ // }
34
+ // };
35
+ // global.ZE_Init = {};
36
+ // global.String.prototype.contains = function (text) {
37
+ // return this.indexOf(text) != -1;
38
+ // };
39
+ // global.TestUtils = TestUtils;
40
+ // // let xmlReq = XMLHttpRequest;
41
+ // // window.XMLHttpRequest = function () {
42
+ // // let xmlReqCopy = new xmlReq();
43
+ // // let originalOpen = xmlReqCopy.open;
44
+ // // xmlReqCopy.open = function () {
45
+ // // if (arguments[1].indexOf('http') != 0) {
46
+ // // arguments[1] = mockDomain + arguments[1];
47
+ // // }
48
+ // // return originalOpen.apply(this, arguments);
49
+ // // };
50
+ // // return xmlReqCopy;
51
+ // // };
52
+
53
+ // TestUtils.scryRenderedComponentsWithTestid = function (dom, name) {
54
+ // let componentList = TestUtils.findAllInRenderedTree(dom, (i, j) => {
55
+ // if (TestUtils.isDOMComponent(i)) {
56
+ // let val = i.getAttribute('data-id');
57
+ // if (typeof val !== 'undefined' && val == name) {
58
+ // return true;
59
+ // }
60
+ // return false;
61
+ // }
62
+ // });
63
+ // return componentList;
64
+ // };
65
+
66
+ // TestUtils.findRenderedComponentsWithTestid = function (dom, name) {
67
+ // let list = TestUtils.scryRenderedComponentsWithTestid(dom, name);
68
+ // if (list.length !== 1) {
69
+ // throw new Error(
70
+ // `Did not find exactly one match (found: ${list.length}) ` +
71
+ // `for data-id:${name}`
72
+ // );
73
+ // }
74
+ // return list[0];
75
+ // };
76
+
77
+ // global.render = function (Component, props) {
78
+ // const renderedDOM = TestUtils.renderIntoDocument(<Component {...props} />);
79
+ // return {
80
+ // props,
81
+ // renderedDOM
82
+ // };
83
+ // };
84
+
85
+ // global.setup = function (Component, props, state) {
86
+ // let router = {
87
+ // router: {
88
+ // push() { },
89
+ // createHref(ob) {
90
+ // return ob.pathname;
91
+ // },
92
+ // isActive() {
93
+ // return true;
94
+ // },
95
+ // replace() { },
96
+ // go() { },
97
+ // goBack() { },
98
+ // goForward() { },
99
+ // setRouteLeaveHook() { },
100
+ // getState() { }
101
+ // },
102
+ // store: {
103
+ // getState() {
104
+ // return state;
105
+ // }
106
+ // }
107
+ // };
108
+ // // var store = {
109
+ // // store:{
110
+ // // getState:function(){return state;}
111
+ // // }
112
+ // // }
113
+ // var Component = higherComponent(Component, router);
114
+ // const renderedDOM = TestUtils.renderIntoDocument(
115
+ // <Component {...props} />,
116
+ // router
117
+ // );
118
+ // return {
119
+ // props,
120
+ // renderedDOM
121
+ // };
122
+ // };
123
+
124
+ // function higherComponent(ActualComponent, context) {
125
+ // if (context) {
126
+ // class HigherComponent extends React.Component {
127
+ // constructor() {
128
+ // super();
129
+ // }
130
+
131
+ // getChildContext() {
132
+ // return context;
133
+ // }
134
+
135
+ // render() {
136
+ // return <ActualComponent {...this.props} />;
137
+ // }
138
+ // }
139
+
140
+ // HigherComponent.childContextTypes = {
141
+ // router: PropTypes.any,
142
+ // store: PropTypes.any
143
+ // };
144
+
145
+ // return HigherComponent;
146
+ // }
147
+ // return ActualComponent;
148
+ // }
149
+ // global.window.matchMedia =
150
+ // window.matchMedia ||
151
+ // function () {
152
+ // return {
153
+ // matches: false,
154
+ // addListener() { },
155
+ // removeListener() { }
156
+ // };
157
+ // };
158
+ // // global.renderHTML = function(comp) {
159
+ // // return ReactDOM.findDOMNode(comp);
160
+ // // };
161
+
162
+ // global.TestUtils = TestUtils;
163
+ // global.getI18NValue = function (inp) {
164
+ // return inp;
165
+ // };
@@ -0,0 +1,61 @@
1
+ const { spawn } = require('child_process')
2
+ const path = require('path');
3
+ const getFilePathWithExtension = require('../../utils/getFilePath');
4
+ const { chromium } = require('@playwright/test');
5
+ const { Logger } = require('../../utils/logger');
6
+ const { getBinPath } = require('../../utils/rootPath');
7
+
8
+ const userArgs = process.argv.slice(3);
9
+
10
+ const playwrightPath = path.resolve(getBinPath(), getFilePathWithExtension('playwright'));
11
+ const command = playwrightPath;
12
+
13
+ const args = ['codegen'].concat(userArgs);
14
+
15
+ function generateCodegen() {
16
+ const childProcess = spawn(command, args, { stdio: 'inherit' });
17
+
18
+ childProcess.on('error', (error) => {
19
+ Logger.log(Logger.FAILURE_TYPE, error);
20
+ })
21
+
22
+ childProcess.on('exit', (code, signal) => {
23
+ Logger.log(Logger.FAILURE_TYPE, `Child Process Exited with Code ${code} and Signal ${signal}`);
24
+
25
+ process.exit();
26
+ });
27
+
28
+ process.on('exit', () => {
29
+ Logger.log(Logger.INFO_TYPE, 'Terminating Playwright Process...');
30
+ //childProcess.kill();
31
+ return;
32
+ });
33
+
34
+ process.on('SIGINT', () => {
35
+ Logger.log(Logger.INFO_TYPE, 'Cleaning up...');
36
+ //childProcess.kill();
37
+ process.exit();
38
+
39
+ });
40
+ }
41
+
42
+
43
+ // Another way to record. Below way will load the url in autheticated state if present
44
+ // function generateCodegen() {
45
+ // (async () => {
46
+ // // Make sure to run headed.
47
+ // const browser = await chromium.launch({ headless: false });
48
+
49
+ // // Setup context however you like.
50
+ // const context = await browser.newContext({ storageState: path.resolve(process.cwd(), 'playwright/.auth/user.json') });
51
+ // await context.route('**/*', route => route.continue());
52
+
53
+ // // Pause the page, and start recording manually.
54
+ // const page = await context.newPage();
55
+ // console.log(userArgs.join(''));
56
+ // await page.goto(`https://${userArgs.join('')}`);
57
+ // await page.pause();
58
+ // })();
59
+ // }
60
+
61
+ module.exports = generateCodegen;
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ CUSTOM_COMMANDS: ['mode']
3
+ }
@@ -0,0 +1,24 @@
1
+ const { readFileSync } = require('fs');
2
+ const path = require('path');
3
+
4
+
5
+
6
+ function initializeEnvConfig(mode = 'dev') {
7
+ try {
8
+ const configFile = readFileSync(path.resolve(process.cwd(), './uat/config.json'));
9
+
10
+ const configJSON = JSON.parse(configFile);
11
+ process.env.mode = mode;
12
+ for (const key in configJSON[mode]) {
13
+ process.env[key] = configJSON[mode][key];
14
+ }
15
+ } catch (err) {
16
+ throw new Error('Config File Not Exists. Please provide a config file to intiailize the environment variables')
17
+ }
18
+
19
+ }
20
+
21
+
22
+ module.exports = {
23
+ initializeEnvConfig
24
+ };
@@ -0,0 +1,81 @@
1
+ const { expect, test: base } = require('@playwright/test');
2
+ // function test(descrition, callback) {
3
+ // return test(descrition, ({ page }) => {
4
+ // const { locator, ...custompage } = page
5
+ // callback({ page: custompage })
6
+ // })
7
+ // }
8
+
9
+ // class FilteredPage {
10
+ // constructor(page) {
11
+ // this.page = page;
12
+ // this.allowedMethods = ['getByText', 'getByTitle'];
13
+ // this.context = page.context;
14
+ // }
15
+
16
+ // goto(...args) {
17
+ // return this.page['goto'](...args);
18
+ // }
19
+
20
+
21
+ // getByRole(...args) {
22
+ // return this.page['getByRole'](...args);
23
+ // }
24
+ // }
25
+
26
+
27
+ // function FilteredPage(page) {
28
+ // return {
29
+ // getByRole: () => {
30
+ // throw new Error('You cannnot use getByRole property')
31
+ // }
32
+ // }
33
+ // }
34
+
35
+ const test = base.extend({
36
+ page: async ({ baseURL, page }, use) => {
37
+ // const proxyPage = new Proxy(page, {
38
+ // get: function (obj, prop) {
39
+ // console.log('Gettig Priop', prop);
40
+ // let filterMethod = FilteredPage(page)[prop];
41
+ // if (filterMethod) {
42
+ // return filterMethod;
43
+ // } else {
44
+ // return obj[prop] ? obj[prop] : 'property does not exist';
45
+ // }
46
+ // }
47
+ // })
48
+ page.getBaseUrl = function () {
49
+ if (process.env.mode === 'dev') {
50
+ return `${process.env.domain}?devURL=${process.env.devUrl}`;
51
+ }
52
+ return `${process.env.domain}`;
53
+ }
54
+
55
+ page.getCustomPageUrl = function (url) {
56
+ if (process.env.mode === 'dev') {
57
+ return `${process.env.domain}/${url}?devURL=${process.env.devUrl}`
58
+ }
59
+ return `${process.env.domain}/${url}`
60
+ }
61
+ await use(page);
62
+
63
+
64
+ //await use(new FilteredPage(page));
65
+
66
+ // await use(async (page) => {
67
+ // delete page.getByTestId;
68
+ // await page;
69
+ // });
70
+
71
+ },
72
+ context: async ({ context }, use) => {
73
+ await context.addInitScript(() => window.localStorage.setItem('isDnBannerHide', true));
74
+ await use(context);
75
+ }
76
+ })
77
+
78
+ module.exports = {
79
+ expect,
80
+ test
81
+ }
@@ -0,0 +1,18 @@
1
+ const { existsSync } = require('fs');
2
+ const path = require('path');
3
+
4
+ const fileName = 'test.config.js';
5
+
6
+ function generateConfigFromFile() {
7
+ const filePath = path.resolve(process.cwd(), fileName);
8
+
9
+ if (existsSync(filePath)) {
10
+ const config = require(filePath);
11
+ return config;
12
+ }
13
+
14
+ return {};
15
+ }
16
+
17
+
18
+ module.exports = generateConfigFromFile;
@@ -0,0 +1,44 @@
1
+ const { spawn } = require('child_process');
2
+ const path = require('path');
3
+ const { Logger } = require('../../utils/logger');
4
+ const getFilePathWithExtension = require('../../utils/getFilePath');
5
+ const { getBinPath } = require('../../utils/rootPath');
6
+
7
+
8
+ const userArgs = process.argv.slice(3);
9
+
10
+ const playwrightPath = path.resolve(getBinPath(), getFilePathWithExtension('playwright'));;
11
+ const command = playwrightPath;
12
+ const reportPath = path.resolve(process.cwd(), './playwright-report');
13
+
14
+
15
+ const args = ['show-report', reportPath].concat(userArgs);
16
+
17
+ function generateReport() {
18
+ const childProcess = spawn(command, args, { stdio: 'inherit' });
19
+ childProcess.on('error', (error) => {
20
+ Logger.log(Logger.FAILURE_TYPE, error);
21
+ })
22
+
23
+ childProcess.on('exit', (code, signal) => {
24
+ Logger.log(Logger.FAILURE_TYPE, `Child Process Exited with Code ${code} and Signal ${signal}`);
25
+
26
+ process.exit();
27
+ });
28
+
29
+ process.on('exit', () => {
30
+ Logger.log(Logger.INFO_TYPE, 'Terminating Playwright Process...');
31
+ childProcess.kill();
32
+ return;
33
+ });
34
+
35
+ process.on('SIGINT', () => {
36
+ Logger.log(Logger.INFO_TYPE, 'Cleaning up...');
37
+ childProcess.kill();
38
+ process.exit();
39
+
40
+ });
41
+ }
42
+
43
+
44
+ module.exports = generateReport;
@@ -0,0 +1,64 @@
1
+ const { spawn } = require('child_process');
2
+ const path = require('path');
3
+ const { CUSTOM_COMMANDS } = require('./custom-commands');
4
+ const { cliArgsToObject, objectToCliArgs } = require('../../utils/cliArgsToObject');
5
+ const { initializeEnvConfig } = require('./env-initializer');
6
+ const { Logger } = require('../../utils/logger');
7
+ const getFilePathWithExtension = require('../../utils/getFilePath');
8
+ const generateConfigFromFile = require('./readConfigFile');
9
+ const { getBinPath } = require('../../utils/rootPath');
10
+
11
+
12
+
13
+ // Access the command line arguments
14
+ const userArgs = process.argv.slice(2);
15
+
16
+ const userArgsObject = cliArgsToObject(userArgs);
17
+
18
+ initializeEnvConfig(userArgsObject.mode ? userArgsObject.mode : 'dev');
19
+
20
+
21
+ generateConfigFromFile();
22
+
23
+
24
+
25
+ const playwrightArgs = objectToCliArgs(userArgsObject, (key) => !CUSTOM_COMMANDS.includes(key));
26
+
27
+ // Command and arguments for npx playwright test
28
+ const playwrightPath = path.resolve(getBinPath(), getFilePathWithExtension('playwright'));
29
+
30
+ const command = playwrightPath;
31
+ const args = ['test', '--config', require.resolve('../../../playwright.config.js')].concat(playwrightArgs);
32
+
33
+
34
+ function createTestRunner() {
35
+ // Spawn the child process
36
+
37
+ const childProcess = spawn(command, args, { stdio: 'inherit' });
38
+
39
+ childProcess.on('error', (error) => {
40
+ Logger.log(Logger.FAILURE_TYPE, error);
41
+ })
42
+
43
+ childProcess.on('exit', (code, signal) => {
44
+ Logger.log(Logger.FAILURE_TYPE, `Child Process Exited with Code ${code} and Signal ${signal}`);
45
+
46
+ process.exit();
47
+ });
48
+
49
+ process.on('exit', () => {
50
+ Logger.log(Logger.INFO_TYPE, 'Terminating Playwright Process...');
51
+ //childProcess.kill();
52
+ return;
53
+ });
54
+
55
+ process.on('SIGINT', () => {
56
+ Logger.log(Logger.INFO_TYPE, 'Cleaning up...');
57
+ //childProcess.kill();
58
+ process.exit();
59
+
60
+ });
61
+ }
62
+
63
+
64
+ module.exports = createTestRunner;
package/src/index.js ADDED
@@ -0,0 +1,9 @@
1
+ const { expect, test } = require('./core/playwright/index');
2
+ const { fireEvent, render } = require('@testing-library/react');
3
+
4
+ module.exports = {
5
+ expect,
6
+ test,
7
+ fireEvent,
8
+ render
9
+ }
package/src/lib/cli.js ADDED
@@ -0,0 +1,35 @@
1
+ const createTestRunner = require("../core/playwright/test-runner");
2
+ const createJestRunner = require('../core/jest/runner/jest-runner');
3
+ const generateReport = require("../core/playwright/report-generator");
4
+ const generateCodegen = require('../core/playwright/codegen')
5
+ const { Logger } = require("../utils/logger");
6
+
7
+ const [, , option] = process.argv;
8
+ const args = process.argv.slice(3);
9
+ const appPath = process.cwd();
10
+
11
+
12
+ switch (option) {
13
+ case 'test': {
14
+ Logger.log(Logger.SUCCESS_TYPE, 'Running Tests..');
15
+ createTestRunner();
16
+ //createJestRunner();
17
+ break;
18
+ }
19
+ case 'report': {
20
+ // console.log('\x1b[36mGenerating Reports...\x1b[0m');
21
+ Logger.log(Logger.SUCCESS_TYPE, 'Generating Reports...');
22
+ generateReport();
23
+ break;
24
+ }
25
+ case 'codegen': {
26
+ Logger.log(Logger.INFO_TYPE, 'The purpose of codegen is to assist developer .....')
27
+ generateCodegen();
28
+ break;
29
+ }
30
+
31
+ default: {
32
+ console.log('Supported Commands test and report')
33
+ break;
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ function cliArgsToObject(cliArgs, isKeyNeedToBeAdded) {
2
+ const processEnv = {};
3
+ cliArgs.forEach(option => {
4
+ if (/^--./.test(option)) {
5
+ const equIndex = option.indexOf('=');
6
+ let key = option.slice(2, equIndex);
7
+ let value = option.slice(equIndex + 1);
8
+ if (equIndex === -1) {
9
+ key = option.slice(2);
10
+ value = true;
11
+ }
12
+ processEnv[key] = value;
13
+ }
14
+ });
15
+ return processEnv;
16
+ }
17
+
18
+ function objectToCliArgs(objectToBeConverted, isKeyNeedToBeAdded) {
19
+ const argsArray = [];
20
+
21
+ Object.keys(objectToBeConverted).forEach(key => {
22
+ if (isKeyNeedToBeAdded(key)) {
23
+ if (typeof objectToBeConverted[key] === 'boolean' && objectToBeConverted[key]) {
24
+ argsArray.push(`--${key}`)
25
+ } else {
26
+ argsArray.push(`--${key}=${objectToBeConverted[key]}`)
27
+ }
28
+ }
29
+ })
30
+
31
+ return argsArray;
32
+ }
33
+
34
+
35
+ module.exports = { cliArgsToObject, objectToCliArgs };
@@ -0,0 +1,9 @@
1
+ const { platform } = require('os');
2
+
3
+ const isWindows = platform().toLowerCase() === 'win32';
4
+
5
+ function getFilePathWithExtension(binName) {
6
+ return isWindows ? `${binName}.cmd` : binName;
7
+ }
8
+
9
+ module.exports = getFilePathWithExtension;
@@ -0,0 +1,28 @@
1
+ const SUCCESS_TYPE = 'success';
2
+ const FAILURE_TYPE = 'failure';
3
+ const INFO_TYPE = 'info';
4
+
5
+ function logger() {
6
+ this.colors = {
7
+ 'success': ['\x1b[36m', '\x1b[0m'],
8
+ 'failure': ['\x1b[31m', '\x1b[0m'],
9
+ 'info': ['\x1b[33m', '\x1b[0m']
10
+ }
11
+ this.consoleLogger = console;
12
+ return {
13
+ SUCCESS_TYPE,
14
+ FAILURE_TYPE,
15
+ INFO_TYPE,
16
+ error: () => { },
17
+ info: () => { },
18
+ log: (type, message) => {
19
+ const color = this.colors[type];
20
+ this.consoleLogger.log(`${color[0]}${message}${color[1]}`)
21
+ }
22
+ }
23
+ }
24
+
25
+
26
+ module.exports = {
27
+ Logger: logger()
28
+ }
@@ -0,0 +1,19 @@
1
+ const path = require('path')
2
+
3
+ function getRootPath() {
4
+ return module.paths[0];
5
+ }
6
+
7
+ function getRootNodeModulesPath() {
8
+ return path.resolve(getRootPath(), 'node_modules');
9
+ }
10
+
11
+ function getBinPath() {
12
+ return path.resolve(getRootPath(), '..', '.bin');
13
+ }
14
+
15
+ module.exports = {
16
+ getRootPath,
17
+ getBinPath,
18
+ getRootNodeModulesPath
19
+ }