chore: perauset customer project
This commit is contained in:
141
e2e/tests/steps/browser/common.steps.ts
Normal file
141
e2e/tests/steps/browser/common.steps.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import { Given, When, Then } from '@cucumber/cucumber'
|
||||
import { expect } from '@playwright/test'
|
||||
import { BrowserWorld } from '../../support/browser-world.js'
|
||||
import { browserConfig } from '../../support/browser-config.js'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Given
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Given('I am on the login page', async function (this: BrowserWorld) {
|
||||
await this.navigateTo('/login')
|
||||
})
|
||||
|
||||
Given('I am logged in as {string}', async function (this: BrowserWorld, email: string) {
|
||||
await this.login(email)
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// When — navigation
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
When('I navigate to {string}', async function (this: BrowserWorld, path: string) {
|
||||
await this.navigateTo(path)
|
||||
})
|
||||
|
||||
When('I click {string}', async function (this: BrowserWorld, name: string) {
|
||||
const page = this.getPage()
|
||||
// Try button first, then link
|
||||
const button = page.getByRole('button', { name })
|
||||
if (await button.isVisible().catch(() => false)) {
|
||||
await button.click()
|
||||
} else {
|
||||
await page.getByRole('link', { name }).click()
|
||||
}
|
||||
await page.waitForLoadState('networkidle').catch(() => {})
|
||||
})
|
||||
|
||||
When('I click {string} in the sidebar', async function (this: BrowserWorld, name: string) {
|
||||
const page = this.getPage()
|
||||
// Mantine NavLink renders as an <a> WITHOUT href (navigation is via onClick), so
|
||||
// it has no implicit "link" role — target the label text inside the navbar.
|
||||
// Some labels are duplicated (e.g. "My Stays" maps to both /my/stays and /stays
|
||||
// due to the nav.stays == nav.my_stays i18n collision); first() picks the
|
||||
// personal-section entry, which appears first in DOM order.
|
||||
const navItem = page
|
||||
.locator('.mantine-AppShell-navbar')
|
||||
.getByText(name, { exact: true })
|
||||
.first()
|
||||
await navItem.scrollIntoViewIfNeeded()
|
||||
await navItem.click()
|
||||
await page.waitForLoadState('networkidle').catch(() => {})
|
||||
})
|
||||
|
||||
When('I click tab {string}', async function (this: BrowserWorld, name: string) {
|
||||
const page = this.getPage()
|
||||
await page.getByRole('tab', { name }).click()
|
||||
await page.waitForLoadState('networkidle').catch(() => {})
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// When — form interactions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
When(
|
||||
'I fill in {string} with {string}',
|
||||
async function (this: BrowserWorld, label: string, value: string) {
|
||||
await this.fillField(label, value)
|
||||
}
|
||||
)
|
||||
|
||||
When(
|
||||
'I select {string} from {string}',
|
||||
async function (this: BrowserWorld, value: string, label: string) {
|
||||
await this.selectOption(label, value)
|
||||
}
|
||||
)
|
||||
|
||||
When(
|
||||
'I pick date {string} for {string}',
|
||||
async function (this: BrowserWorld, day: string, label: string) {
|
||||
const page = this.getPage()
|
||||
// Close any open calendar/dropdown first
|
||||
await page.keyboard.press('Escape')
|
||||
await page.waitForTimeout(300)
|
||||
// Mantine DatePickerInput: the label text and button are wrapped in the same container
|
||||
// Use a CSS selector to find the right DatePickerInput by its label
|
||||
const wrapper = page.locator(`text="${label}" >> xpath=ancestor::div[contains(@class, "mantine-DatePickerInput-root") or contains(@class, "mantine-InputWrapper-root")][1]`)
|
||||
const btn = wrapper.locator('button').first()
|
||||
if (await btn.count() > 0) {
|
||||
await btn.click({ timeout: 10_000 })
|
||||
} else {
|
||||
// Fallback: just try getByLabel
|
||||
await page.getByLabel(label).click({ timeout: 10_000 })
|
||||
}
|
||||
// Wait for calendar popover to appear
|
||||
await page.waitForTimeout(500)
|
||||
// Click the day number — try table buttons with matching text
|
||||
await page.locator('table button').filter({ hasText: new RegExp(`^${day}$`) }).first().click()
|
||||
// Close the calendar popover
|
||||
await page.waitForTimeout(300)
|
||||
}
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Then — assertions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Then('I should see {string}', async function (this: BrowserWorld, text: string) {
|
||||
await this.expectText(text)
|
||||
})
|
||||
|
||||
Then('I should not see {string}', async function (this: BrowserWorld, text: string) {
|
||||
await this.expectNoText(text)
|
||||
})
|
||||
|
||||
Then('I should see heading {string}', async function (this: BrowserWorld, text: string) {
|
||||
await this.expectHeading(text)
|
||||
})
|
||||
|
||||
Then('I should be on {string}', async function (this: BrowserWorld, path: string) {
|
||||
const page = this.getPage()
|
||||
await page.waitForURL((url) => url.pathname.includes(path), { timeout: 10_000 })
|
||||
expect(page.url()).toContain(path)
|
||||
})
|
||||
|
||||
Then(
|
||||
'the sidebar should show {string}',
|
||||
async function (this: BrowserWorld, text: string) {
|
||||
const page = this.getPage()
|
||||
const sidebar = page.locator('.mantine-AppShell-navbar')
|
||||
await expect(sidebar.getByText(text)).toBeVisible({ timeout: 10_000 })
|
||||
}
|
||||
)
|
||||
|
||||
Then(
|
||||
'the {string} field should contain {string}',
|
||||
async function (this: BrowserWorld, label: string, value: string) {
|
||||
const page = this.getPage()
|
||||
await expect(page.getByLabel(label)).toHaveValue(value, { timeout: 5_000 })
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user