Skip to content

Commit 2b4e7c6

Browse files
committed
HP-1144: fix PW tests
1 parent a1ee5f6 commit 2b4e7c6

File tree

4 files changed

+84
-105
lines changed

4 files changed

+84
-105
lines changed

docs/Testing.md

+12
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,18 @@ or run a specific test
6969
npm run test vendor/hiqdev/hipanel-module-document/tests/playwright/e2e/manager/document.spec.ts # run a specific test
7070
```
7171

72+
or running codegen
73+
74+
```shell
75+
npx codegen http://local.hipanel.advancedhosting.com
76+
```
77+
78+
or run tests with debug
79+
80+
```shell
81+
PWDEBUG=1 npm run test vendor/hiqdev/hipanel-module-document/tests/playwright/e2e/manager/document.spec.ts # run a specific test
82+
```
83+
7284
In order to add new module for testing you should add module folder name to `playwright.config.ts`
7385

7486
```javascript

tests/playwright/common/auth.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type Credential = {
1313
}
1414

1515
export async function login(page: Page, credential: Credential) {
16-
await page.goto("/site/login");
16+
await page.goto(`${process.env.URL}/site/login`);
1717
await page.fill("#loginform-username", credential.login);
1818
await page.fill("#loginform-password", credential.password);
1919
await page.click("#login-form button[type=submit]");

tests/playwright/fixtures.ts

+52-104
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,55 @@
1-
import { test as base, type Page, type BrowserContext } from "@playwright/test";
2-
import { login, type Credentials } from "@hipanel-core/common/auth";
3-
1+
import { type Page, test as base, type TestInfo } from "@playwright/test";
2+
import * as path from "path";
3+
import * as fs from "fs";
4+
import { login } from "@hipanel-core/common/auth";
5+
6+
const testClients = {
7+
client: { login: "hipanel_test_user", password: "random" },
8+
admin: { login: "hipanel_test_admin", password: "random" },
9+
manager: { login: "hipanel_test_manager", password: "random" },
10+
seller: { login: "hipanel_test_reseller", password: "random" },
11+
};
12+
13+
export { expect } from "@playwright/test";
414
export const test = base.extend<{
5-
clientContext: BrowserContext, clientPage: Page,
6-
adminContext: BrowserContext, adminPage: Page,
7-
managerContext: BrowserContext, managerPage: Page,
8-
sellerContext: BrowserContext, sellerPage: Page,
9-
}, {
10-
clientState: any,
11-
adminState: any,
12-
managerState: any,
13-
sellerState: any,
14-
} & Credentials>({
15-
client: [{ login: "", password: "" }, { scope: "worker", option: true }],
16-
admin: [{ login: "", password: "" }, { scope: "worker", option: true }],
17-
manager: [{ login: "", password: "" }, { scope: "worker", option: true }],
18-
seller: [{ login: "", password: "" }, { scope: "worker", option: true }],
19-
// Client
20-
clientState: [async ({ browser, client }, use) => {
21-
const page = await browser.newPage();
22-
await login(page, client);
23-
24-
const cookies = await page.context().cookies();
25-
const state = { cookies };
26-
27-
use(state);
28-
29-
}, { scope: "worker" }],
30-
clientContext: async ({ context, clientState }, use) => {
31-
const { cookies } = clientState;
32-
await context.addCookies(cookies);
33-
34-
use(context);
35-
},
36-
clientPage: async ({ clientContext }, use) => {
37-
const page = await clientContext.newPage();
38-
39-
use(page);
40-
},
41-
// Admin
42-
adminState: [async ({ browser, admin }, use) => {
43-
const page = await browser.newPage();
44-
await login(page, admin);
45-
46-
const cookies = await page.context().cookies();
47-
const state = { cookies };
48-
49-
use(state);
50-
51-
}, { scope: "worker" }],
52-
adminContext: async ({ context, adminState }, use) => {
53-
const { cookies } = adminState;
54-
await context.addCookies(cookies);
55-
56-
use(context);
57-
},
58-
adminPage: async ({ adminContext }, use) => {
59-
const page = await adminContext.newPage();
60-
61-
use(page);
62-
},
63-
// Manager
64-
managerState: [async ({ browser, manager }, use) => {
65-
const page = await browser.newPage();
66-
await login(page, manager);
67-
68-
const cookies = await page.context().cookies();
69-
const state = { cookies };
70-
71-
use(state);
72-
73-
}, { scope: "worker" }],
74-
managerContext: async ({ context, managerState }, use) => {
75-
const { cookies } = managerState;
76-
await context.addCookies(cookies);
77-
78-
use(context);
79-
},
80-
managerPage: async ({ managerContext }, use) => {
81-
const page = await managerContext.newPage();
82-
83-
use(page);
84-
},
85-
// Seller
86-
sellerState: [async ({ browser, seller }, use) => {
87-
const page = await browser.newPage();
88-
await login(page, seller);
89-
90-
const cookies = await page.context().cookies();
91-
const state = { cookies };
92-
93-
use(state);
94-
95-
}, { scope: "worker" }],
96-
sellerContext: async ({ context, sellerState }, use) => {
97-
const { cookies } = sellerState;
98-
await context.addCookies(cookies);
99-
100-
use(context);
101-
},
102-
sellerPage: async ({ sellerContext }, use) => {
103-
const page = await sellerContext.newPage();
104-
105-
use(page);
15+
clientPage: Page,
16+
adminPage: Page,
17+
managerPage: Page,
18+
sellerPage: Page,
19+
}>({
20+
storageState: async ({ browser }, use, testInfo: TestInfo) => {
21+
let actor;
22+
const testTitle = testInfo.title;
23+
["seller", "manager", "client", "admin"].forEach((role: string) => {
24+
if (testTitle.includes(`@${role}`)) {
25+
actor = role;
26+
return;
27+
}
28+
});
29+
if (!actor) {
30+
throw new Error("Test role is not found, the role tag must be present in the test title, for example: @seller, @manager, @client, @admin");
31+
}
32+
// const fileName = path.join(testInfo.project.outputDir, `auth-storage-${actor}`);
33+
const fileName = path.join(process.cwd(), 'tests/_data', `auth-storage-${actor}`);
34+
if (!fs.existsSync(fileName)) {
35+
const page = await browser.newPage({ storageState: undefined });
36+
await login(page, testClients[actor]);
37+
await page.context().storageState({ path: fileName });
38+
await page.close();
39+
}
40+
await use(fileName);
41+
},
42+
// TODO: legacy auth flow compatibility, remove after refactoring from older implementation
43+
sellerPage: async ({ page }, use) => {
44+
await use(page);
45+
},
46+
managerPage: async ({ page }, use) => {
47+
await use(page);
48+
},
49+
adminPage: async ({ page }, use) => {
50+
await use(page);
51+
},
52+
clientPage: async ({ page }, use) => {
53+
await use(page);
10654
},
10755
});

tests/playwright/input/TreeSelect.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Locator, Page } from "@playwright/test";
2+
3+
export default class TreeSelect {
4+
private inputLocator: Locator;
5+
6+
private constructor(private page: Page, fieldId: string) {
7+
this.inputLocator = page.locator(`label[for="${fieldId}"] + div > .vue-treeselect input[type="text"]`);
8+
}
9+
10+
static field(page: Page, fieldId: string): TreeSelect {
11+
return new TreeSelect(page, fieldId);
12+
}
13+
14+
async setValue(value: string) {
15+
await this.inputLocator.click();
16+
await this.inputLocator.fill(value);
17+
await this.page.locator(`label.vue-treeselect__label >> text=/^${value}$/i`).last().click();
18+
}
19+
}

0 commit comments

Comments
 (0)