File size: 3,639 Bytes
936b397 | 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import type { Locator, Page } from '@playwright/test'
import { expect } from '@playwright/test'
import {
ZonedDateTime,
ZoneOffset,
ChronoUnit,
DateTimeFormatter
} from '@js-joda/core'
export function currentTime(): ZonedDateTime {
return ZonedDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.SECONDS)
}
export function timeToISO(ts: ZonedDateTime): string {
return ts.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
}
export async function expectLiveViewConnected(page: Page) {
await expect
.poll(() => page.locator('.phx-connected').count())
.toBeGreaterThan(0)
}
export function randomID() {
return Math.random().toString(16).slice(2)
}
export const tabButton = (page: Page | Locator, label: HasTextArg) =>
page.getByTestId('tab-button').filter({ hasText: label })
export const tabButtonWithDropdown = (
page: Page | Locator,
label: HasTextArg
) => page.getByTestId('tab-button-with-dropdown').filter({ hasText: label })
export const header = (report: Locator, label: HasTextArg) =>
report
.getByTestId('report-header')
.filter({ hasText: label })
.getByRole('button')
export const expectHeaders = async (report: Locator, headers: HaveTextArg) =>
expect(report.getByTestId('report-header')).toHaveText(headers)
export const expectRows = async (report: Locator, labels: HaveTextArg) =>
expect(
report.getByTestId('report-row').getByTestId('dimension-value')
).toHaveText(labels)
export const rowLink = (report: Locator, label: HasTextArg) =>
report
.getByTestId('report-row')
.filter({ hasText: label })
.getByTestId('dimension-value')
export const expectMetricValues = async (
report: Locator,
label: HasTextArg,
values: HaveTextArg
) =>
expect(
report
.getByTestId('report-row')
.filter({ hasText: label })
.getByTestId('metric-value')
).toHaveText(values)
export const dropdown = (report: Locator) =>
report.getByTestId('dropdown-items')
// Needed before opening dropdown again right after it closes (usually, when picking an item).
// There's a leave transition for the dropdown and interacting with the dropdown opener
// during the transition may mean that the dropdown doesn't actually open.
export const expectDropdownClosed = async (report: Locator) =>
expect(dropdown(report)).toHaveCount(0)
export const searchInput = (report: Locator) =>
report.getByTestId('search-input')
export const modal = (page: Page) => page.locator('.modal')
export const detailsLink = (report: Locator) =>
report.getByRole('link', { name: 'View details' })
export const closeModalButton = (page: Page) =>
page.getByRole('button', { name: 'Close modal' })
export const filterButton = (page: Page) =>
page.getByRole('button', { name: 'Filter', exact: true })
export const filterItemButton = (page: Page, label: HasTextArg) =>
page.getByTestId('filtermenu').getByRole('link', { name: label, exact: true })
export const applyFilterButton = (page: Page, { disabled = false } = {}) =>
page.getByRole('button', {
name: 'Apply filter',
disabled
})
export const filterRow = (page: Page, key: string) =>
page.getByTestId(`filter-row-${key}`)
export const suggestedItem = (scoped: Locator, url: string) =>
scoped.getByRole('listitem').filter({ hasText: url })
export const filterOperator = (scoped: Locator) =>
scoped.getByTestId('filter-operator')
export const filterOperatorOption = (scoped: Locator, option: HasTextArg) =>
scoped.getByTestId('filter-operator-option').filter({ hasText: option })
type HaveTextArg = string | RegExp | ReadonlyArray<string | RegExp>
type HasTextArg = string | RegExp
|