Skip to content

Commit

Permalink
Merge branch 'SnowdogApps#8-page-end-selector' into test
Browse files Browse the repository at this point in the history
  • Loading branch information
anqaka committed May 14, 2024
2 parents 53bf0ff + 5bdf2e7 commit 3f65709
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 6 deletions.
33 changes: 30 additions & 3 deletions components/AuditForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ if (baseAuditId) {
} else {
setValues({
pages: baseAudit.config.noAxe
? [{ selector: '', url: '' }]
? [{ selector: '', endSelector: '', url: '' }]
: baseAudit.config.pages,
title: baseAudit.config.title,
project: baseAudit.projects?.id,
Expand Down Expand Up @@ -267,7 +267,7 @@ const onAuditProcessingDialogClose = (resetAuditForm: boolean = true) => {
</div>

<div class="w-full">
<label :for="`selector-${index}`">HTML Selector</label>
<label :for="`selector-${index}`">HTML Selector to</label>
<InputText
:id="`selector-${index}`"
v-model="page.value.selector"
Expand All @@ -289,6 +289,33 @@ const onAuditProcessingDialogClose = (resetAuditForm: boolean = true) => {
selector allowed. If empty whole document will be tested.
</small>
</div>
<div class="col-start-2 w-full">
<label :for="`selector-end-${index}`"
>HTML Selector at the end of the page</label
>
<InputText
:id="`selector-end-${index}`"
v-model="page.value.endSelector"
:name="`pages[${index}].endSelector`"
class="w-full"
:aria-describedby="`selector-end-help-${index}`"
:data-testid="`audit-page-selector-end-field-${index}`"
:class="[
{
'p-invalid':
(errors[`pages[${index}].endSelector` as `pages.${number}.endSelector`] ||
errors[`pages[${index}]` as `pages.${number}`]) &&
isSubmitted,
},
]"
/>
<small :id="`selector-end-help-${index}`">
Sometimes dynamic page is not fully loaded when automatic
tests are conducted. To make sure all elements on the page are
available, provide the element at the end of the page, use
.class or #id to choose selector, just one selector allowed.
</small>
</div>
<small
v-if="errors[`pages[${index}]` as `pages.${number}`] && isSubmitted"
class="p-error w-full"
Expand Down Expand Up @@ -321,7 +348,7 @@ const onAuditProcessingDialogClose = (resetAuditForm: boolean = true) => {
:pt="{
icon: { 'aria-hidden': true },
}"
@click="pushPage({ url: '', selector: '' })"
@click="pushPage({ url: '', selector: '', endSelector: '' })"
/>
</AccordionTab>
<AccordionTab header="General">
Expand Down
8 changes: 8 additions & 0 deletions pages/audit/report/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ const completeReport = async () => {
{{ page.selector }}
</code>
</template>
<template v-if="page.endSelector?.length">
- selector of the element at the end of the page:
<code
class="break-words rounded-md bg-gray-100 px-2 py-1"
>
{{ page.endSelector }}
</code>
</template>
</li>
</ul>
</template>
Expand Down
24 changes: 22 additions & 2 deletions server/axe-runner/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const doTest = async function (

await page.setViewportSize(size)

for await (const { url, selector } of pages) {
for await (const { url, selector, endSelector } of pages) {
let result: AxeResults | undefined
const errors: ResultError[] = []

Expand All @@ -73,6 +73,24 @@ export const doTest = async function (

const axe = await new AxeBuilder({ page })

if (endSelector) {
await page
.locator(endSelector)
.waitFor()
.then(async () => {
await page.evaluate(() =>
window.scrollTo(0, document.body.scrollHeight)
)
})
.catch(() =>
errors.push({
url,
message:
'Selector of element at the end of the page does not exist.',
})
)
}

if (selector) {
await page
.locator(selector)
Expand All @@ -95,7 +113,9 @@ export const doTest = async function (
result = await axe.analyze()
}

results.push(parseResults(auditId, size, errors, result, selector))
results.push(
parseResults(auditId, size, errors, result, selector, endSelector)
)
}

if (process.env.dev) {
Expand Down
4 changes: 3 additions & 1 deletion server/axe-runner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ export const parseResults = function (
size: ViewportSize,
errors?: ResultError[],
results?: AxeResults,
selector?: string
selector?: string,
endSelector?: string
): TestResult {
return {
audit_id: auditId,
selector: selector || null,
end_selector: endSelector || null,
size: `${size.width},${size.height}`,
results: results ? trimResults(results) : null,
errors,
Expand Down
1 change: 1 addition & 0 deletions sql/02_tables/05_axe.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ create table axe (
created_at timestamp default current_timestamp not null,
audit_id serial references public.audits on delete cascade not null,
selector text,
end_selector text,
size text,
results JSONB not null DEFAULT '{}'::jsonb,
form_data JSONB not null DEFAULT '{}'::jsonb,
Expand Down
1 change: 1 addition & 0 deletions types/audit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { auditTemplate } from '~/data/auditTemplate'

export interface Page {
selector?: string | undefined
endSelector?: string | undefined
url: string
}

Expand Down
2 changes: 2 additions & 0 deletions types/axe-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type ResultError = {
export interface TestResult {
audit_id: string
selector: string | null
end_selector: string | null
size: string
results: TrimmedResults | null
errors?: ResultError[]
Expand All @@ -32,6 +33,7 @@ export type BasicAuth = {

export type Page = {
selector?: string
endSelector?: string
url: string
}

Expand Down
3 changes: 3 additions & 0 deletions types/supabase-latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface Database {
id: number
results: Json | null
selector: string | null
end_selector: string | null
size: string | null
}
Insert: {
Expand All @@ -80,6 +81,7 @@ export interface Database {
id?: number
results?: Json | null
selector?: string | null
end_selector?: string | null
size?: string | null
}
Update: {
Expand All @@ -90,6 +92,7 @@ export interface Database {
id?: number
results?: Json | null
selector?: string | null
end_selector?: string | null
size?: string | null
}
Relationships: [
Expand Down
3 changes: 3 additions & 0 deletions types/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export interface Database {
results: Results
errors: Json[] | null
selector: string | null
end_selector: string | null
size: string | null
form_data: FormData | null
}
Expand All @@ -115,6 +116,7 @@ export interface Database {
id?: number
results?: Results
selector?: string | null
end_selector?: string | null
size?: string | null
form_data?: FormData | null
}
Expand All @@ -124,6 +126,7 @@ export interface Database {
id?: number
results?: Results
selector?: string | null
end_selector?: string | null
size?: string | null
form_data?: FormData | null
}
Expand Down
5 changes: 5 additions & 0 deletions validation/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ export const auditFormSchema = object({
object().shape({
url: string(),
selector: string(),
endSelector: string(),
})
)
.default([
{
endSelector: '',
selector: '',
url: '',
},
Expand All @@ -48,12 +50,14 @@ export const auditFormSchema = object({
.shape({
url: string().url().required(),
selector: string(),
endSelector: string(),
})
.test('isUnique', `The entry is not unique`, function (currentPage) {
const pages = this.parent
const count = pages.filter(
(page: Page) =>
page.selector === currentPage.selector &&
page.endSelector === currentPage.endSelector &&
page.url === currentPage.url
).length
return count <= 1
Expand All @@ -63,6 +67,7 @@ export const auditFormSchema = object({
.default([
{
selector: '',
endSelector: '',
url: '',
},
])
Expand Down

0 comments on commit 3f65709

Please sign in to comment.