-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathposition-form.page.ts
More file actions
78 lines (67 loc) · 3.24 KB
/
position-form.page.ts
File metadata and controls
78 lines (67 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { Page, Locator } from '@playwright/test';
import { BaseFormPage } from './base-form.page';
/**
* Position Form Page Object
*
* Covers the create/edit position form (HRAdmin only via route guard).
* Shared behaviour (submit, cancel, validation, success) comes from BaseFormPage.
*
* Angular form fields (from position-form.component.ts):
* positionTitle — required, maxLength(100)
* positionNumber — required, maxLength(50)
* positionDescription — optional, maxLength(500)
* departmentId — required (mat-select)
* salaryRangeId — required (mat-select)
*/
export class PositionFormPage extends BaseFormPage {
readonly titleInput: Locator;
readonly positionNumberInput: Locator;
readonly descriptionInput: Locator;
readonly departmentSelect: Locator;
readonly salaryRangeSelect: Locator;
constructor(page: Page) {
super(page, '/positions');
this.titleInput = page.locator('input[formControlName="positionTitle"]');
this.positionNumberInput = page.locator('input[formControlName="positionNumber"]');
this.descriptionInput = page.locator('textarea[formControlName="positionDescription"]');
this.departmentSelect = page.locator('mat-select[formControlName="departmentId"]');
this.salaryRangeSelect = page.locator('mat-select[formControlName="salaryRangeId"]');
}
protected async isFormStillFilled(): Promise<boolean> {
const value = await this.titleInput.inputValue().catch(() => '');
return value.length > 0;
}
// ── Field fill methods ──────────────────────────────────────────────────
async fillTitle(title: string) {
await this.titleInput.fill(title);
}
async fillPositionNumber(positionNumber: string) {
await this.positionNumberInput.fill(positionNumber);
}
async fillDescription(description: string) {
const isVisible = await this.descriptionInput.isVisible({ timeout: 2000 }).catch(() => false);
if (isVisible) await this.descriptionInput.fill(description);
}
/** Selects the first available option from a mat-select dropdown. */
private async selectFirstOption(select: Locator): Promise<void> {
const isVisible = await select.isVisible({ timeout: 2000 }).catch(() => false);
if (!isVisible) return;
await select.click();
const option = this.page.locator('mat-option').first();
await option.waitFor({ state: 'visible', timeout: 5000 });
await option.click();
}
// ── fillForm convenience method ─────────────────────────────────────────
/**
* Fills all required fields for a position form.
* Automatically selects the first available department and salary range.
* positionNumber defaults to PN-{timestamp} if not provided.
*/
async fillForm(data: { title: string; positionNumber?: string; description?: string }) {
await this.fillTitle(data.title);
await this.fillPositionNumber(data.positionNumber ?? `PN-${Date.now()}`);
await this.selectFirstOption(this.departmentSelect);
await this.selectFirstOption(this.salaryRangeSelect);
if (data.description) await this.fillDescription(data.description);
}
}