plum-e2e 1.0.4 → 1.0.6
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 +7 -6
- package/backend/_scaffold/pages/LoginPage.ts +24 -0
- package/backend/_scaffold/step_definitions/{LoginSteps.js → LoginSteps.ts} +1 -1
- package/backend/_scaffold/utils/constants.ts +1 -0
- package/backend/_scaffold/utils/hooks.ts +36 -0
- package/backend/_scaffold/utils/utils.ts +13 -0
- package/backend/_scaffold/utils/world.ts +25 -0
- package/backend/config/scripts/run-tests.js +19 -6
- package/backend/cucumber.json +3 -2
- package/backend/package-lock.json +3598 -3403
- package/backend/package.json +4 -2
- package/backend/playwright.config.js +3 -3
- package/backend/tsconfig.json +13 -0
- package/frontend/package-lock.json +2894 -2894
- package/package.json +4 -2
- package/backend/_scaffold/pages/LoginPage.js +0 -22
- package/backend/_scaffold/utils/constants.js +0 -3
- package/backend/_scaffold/utils/hooks.js +0 -65
- package/backend/_scaffold/utils/utils.js +0 -10
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Plum makes setting up your testing framework easy. In just a few seconds, you ca
|
|
|
11
11
|
|
|
12
12
|
By combining [Playwright](https://playwright.dev) and [Cucumber](https://cucumber.io), tests are easy to write and read. The code follows a POM (Page Object Model) structure, making it scalable and easy for developers to understand, while Cucumber test cases are written in [Gherkin](https://cucumber.io/docs/gherkin/) format, making them accessible to non-developers as well.
|
|
13
13
|
|
|
14
|
-
You can view, run, schedule tests in a simple UI
|
|
14
|
+
You can view, run, and schedule tests in a simple UI. You can even view the history of your runs in the reports page!
|
|
15
15
|
|
|
16
16
|
**_Pre-requisite:_**
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@ You can view, run, schedule tests in a simple UI and even view the history of yo
|
|
|
19
19
|
|
|
20
20
|
## For Users
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
People that want to use Plum as a test environment for their website.
|
|
23
23
|
|
|
24
24
|
**_I. How to Run:_**
|
|
25
25
|
|
|
@@ -31,7 +31,8 @@ For normal users. People that want to use Plum as a test environment for their w
|
|
|
31
31
|
1. `\tests` folder: This include sample test cases for [SauceLabs](https://www.saucedemo.com/v1/)
|
|
32
32
|
2. `.env` file: Your starting .env file. You can set the BASE_URL to your own site after you're done with the scaffold tests.
|
|
33
33
|
5. There are two ways to start testing:
|
|
34
|
-
1. By running the server. Run:<br/> `plum start to start the server
|
|
34
|
+
1. By running the server. Run:<br/> `plum start` to start the server
|
|
35
|
+
1. Access the UI at: http://localhost:5173/
|
|
35
36
|
2. Without running the server. Recommended while you're writing your tests. Run:<br/> `plum dev <@test-id>`. If no test ID is included, it will run all tests
|
|
36
37
|
|
|
37
38
|
## Basic Structure
|
|
@@ -49,8 +50,8 @@ After you run `plum init`, these files will be created inside your project direc
|
|
|
49
50
|
|
|
50
51
|
## Tutorial
|
|
51
52
|
|
|
52
|
-
1. For a complete guide on how to write tests, visit our [
|
|
53
|
-
2. An easy way to learn is to check the scaffold files starting from the Feature files -> Step Definitions -> Page files and utils/
|
|
53
|
+
1. For a complete guide on how to write tests, visit our [Coming Soon](https://github.com/silverlunah/plum/wiki)
|
|
54
|
+
2. An easy way to learn is to check the scaffold files starting from the Feature files -> Step Definitions -> Page files and utils/world.ts for the CustomWorld initialization. Those are the main files you need to write a test case.
|
|
54
55
|
|
|
55
56
|
## For Developers/Contributors
|
|
56
57
|
|
|
@@ -63,4 +64,4 @@ For people that want to contribute to the project
|
|
|
63
64
|
|
|
64
65
|
## Other
|
|
65
66
|
|
|
66
|
-
Plum is completely free to use! But if you want to share some love, here's my [PayPal](https://www.paypal.me/silverlunah) or [Wise](
|
|
67
|
+
Plum is completely free to use! But if you want to share some love, here's my [PayPal](https://www.paypal.me/silverlunah) or [Wise](https://wise.com/pay/me/janneserjosee)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// loginPage.ts
|
|
2
|
+
import test, { Page } from '@playwright/test';
|
|
3
|
+
import { SAMPLE_CONSTANT } from '../utils/constants';
|
|
4
|
+
import { Utils } from '../utils/utils';
|
|
5
|
+
|
|
6
|
+
export class LoginPage {
|
|
7
|
+
private page: Page;
|
|
8
|
+
private utils: Utils;
|
|
9
|
+
|
|
10
|
+
constructor(page: Page) {
|
|
11
|
+
this.page = page;
|
|
12
|
+
this.utils = new Utils(this.page);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async goToLoginPage() {
|
|
16
|
+
console.log(SAMPLE_CONSTANT);
|
|
17
|
+
await this.utils.goToPage(process.env.BASE_URL as string);
|
|
18
|
+
await this.page.waitForTimeout(3000);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async skipTest() {
|
|
22
|
+
test.skip();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SAMPLE_CONSTANT = 'this is a constant';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Before, After, setWorldConstructor, ITestCaseHookParameter } from '@cucumber/cucumber';
|
|
2
|
+
import { chromium } from 'playwright';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { CustomWorld } from './world';
|
|
6
|
+
import dotenv from 'dotenv';
|
|
7
|
+
|
|
8
|
+
dotenv.config();
|
|
9
|
+
setWorldConstructor(CustomWorld);
|
|
10
|
+
|
|
11
|
+
Before(async function (this: CustomWorld) {
|
|
12
|
+
const isHeadless = process.env.IS_HEADLESS?.toLowerCase() !== 'false';
|
|
13
|
+
|
|
14
|
+
this.browser = await chromium.launch({ headless: isHeadless });
|
|
15
|
+
this.context = await this.browser.newContext();
|
|
16
|
+
this.page = await this.context.newPage();
|
|
17
|
+
|
|
18
|
+
this.initPages(this.page);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
After(async function (this: CustomWorld, scenario: ITestCaseHookParameter) {
|
|
22
|
+
if (scenario.result?.status === 'FAILED' && this.page) {
|
|
23
|
+
const screenshotDir = path.join('reports', 'screenshots');
|
|
24
|
+
if (!fs.existsSync(screenshotDir)) {
|
|
25
|
+
fs.mkdirSync(screenshotDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const screenshotPath = path.join(screenshotDir, `screenshot_${Date.now()}.png`);
|
|
29
|
+
await this.page.screenshot({ path: screenshotPath });
|
|
30
|
+
|
|
31
|
+
const screenshotData = fs.readFileSync(screenshotPath);
|
|
32
|
+
await this.attach(screenshotData, 'image/png');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
await this.browser?.close();
|
|
36
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { IWorldOptions, setWorldConstructor, World } from '@cucumber/cucumber';
|
|
2
|
+
import { Browser, Page, BrowserContext } from 'playwright';
|
|
3
|
+
import { LoginPage } from '../pages/LoginPage';
|
|
4
|
+
import { Utils } from './utils';
|
|
5
|
+
|
|
6
|
+
export class CustomWorld extends World {
|
|
7
|
+
browser!: Browser;
|
|
8
|
+
context!: BrowserContext;
|
|
9
|
+
page!: Page;
|
|
10
|
+
|
|
11
|
+
loginPage!: LoginPage;
|
|
12
|
+
utils!: Utils;
|
|
13
|
+
|
|
14
|
+
constructor(options: IWorldOptions) {
|
|
15
|
+
super(options);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
initPages(page: Page) {
|
|
19
|
+
this.utils = new Utils(page);
|
|
20
|
+
this.loginPage = new LoginPage(page);
|
|
21
|
+
// Add other pages here
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setWorldConstructor(CustomWorld);
|
|
@@ -16,19 +16,32 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
const { execSync } = require('child_process');
|
|
19
|
-
const tag = process.env.TAG;
|
|
19
|
+
const tag = process.env.TAG;
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const baseCommand = [
|
|
23
|
+
'npx',
|
|
24
|
+
'cross-env',
|
|
25
|
+
'TS_NODE_TRANSPILE_ONLY=true',
|
|
26
|
+
'cucumber-js',
|
|
27
|
+
'tests/features/**/*.feature',
|
|
28
|
+
'--require-module',
|
|
29
|
+
'ts-node/register',
|
|
30
|
+
'--require',
|
|
31
|
+
'tests/step_definitions/**/*.ts',
|
|
32
|
+
'--format',
|
|
33
|
+
'json:reports/cucumber_report.json'
|
|
34
|
+
];
|
|
26
35
|
|
|
36
|
+
if (tag) {
|
|
37
|
+
baseCommand.push('--tags', `"${tag}"`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const cucumberCommand = baseCommand.join(' ');
|
|
27
41
|
execSync(cucumberCommand, { stdio: 'inherit' });
|
|
28
42
|
} catch (error) {
|
|
29
43
|
console.error('Tests failed:', error.message);
|
|
30
44
|
} finally {
|
|
31
|
-
// Always run the report generation after tests (even if they fail)
|
|
32
45
|
try {
|
|
33
46
|
execSync('node config/scripts/generate-report.js', { stdio: 'inherit' });
|
|
34
47
|
} catch (error) {
|
package/backend/cucumber.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"default": {
|
|
3
|
-
"require": ["tests/step_definitions/*.
|
|
4
|
-
"featurePaths": ["tests/features/**/*.feature"]
|
|
3
|
+
"require": ["tests/step_definitions/*.ts", "tests/utils/hooks.ts"],
|
|
4
|
+
"featurePaths": ["tests/features/**/*.feature"],
|
|
5
|
+
"requireModule": ["ts-node/register"]
|
|
5
6
|
}
|
|
6
7
|
}
|