Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Fix mobile menu modals not opening for the second time (#1386)
Browse files Browse the repository at this point in the history
* Fix mobile menu modals not opening for the second time

* Fix e2e tests

* Set the default hideOnClickOutside for modal to false

* Make e2e header button test work for mobile and desktop
  • Loading branch information
obulat authored May 4, 2022
1 parent 9b43fcc commit 9c33844
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 14 deletions.
8 changes: 3 additions & 5 deletions src/components/VHeader/VHeaderFilter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@ export default {
open()
}
}
const mobileOptions = {
visible: visibleRef,
'trigger-element': computed(() => nodeRef?.value?.firstChild),
hide: close,
'aria-label': i18n.t('header.filter-button.simple'),
'aria-label': i18n.t('header.filter-button.simple').toString(),
mode: 'mobile',
}
Expand All @@ -118,10 +119,7 @@ export default {
visible: visibleRef,
}
/**
* @type { import('@nuxtjs/composition-api').Ref<{
* 'trigger-element'?: import('@nuxtjs/composition-api').ComputedRef<HTMLElement|null>,
* hide?: () => {}, visible: import('@nuxtjs/composition-api').Ref<boolean>,
* 'aria-label': [string], to?: string, mode?: string }> }
* @type { import('@nuxtjs/composition-api').Ref<{'trigger-element'?: import('@nuxtjs/composition-api').ComputedRef<HTMLElement|null>, hide?: () => void, visible: import('@nuxtjs/composition-api').Ref<boolean>, 'aria-label'?: string, to?: string, mode?: string, hideOnClickOutside?: boolean }> }
*/
const options = ref(mobileOptions)
onMounted(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/VModal/VModalContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const VModalContent = defineComponent({
},
hideOnClickOutside: {
type: Boolean,
default: true,
default: false,
},
autoFocusOnShow: {
type: Boolean,
Expand Down
2 changes: 1 addition & 1 deletion src/composables/use-dialog-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { useFocusOnBlur } from '~/composables/use-focus-on-blur'
/** @typedef {import('./types').ToRefs<InnerProps> & { emit: import('@nuxtjs/composition-api').SetupContext['emit']}} Props */

/**
* @param {Props} props
* @param {Props} params
*/
export function useDialogContent({ emit, ...props }) {
const focusOnBlur = useFocusOnBlur(props)
Expand Down
43 changes: 43 additions & 0 deletions test/playwright/e2e/mobile-menu.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { test, expect } from '@playwright/test'

import {
closeMobileMenu,
openFilters,
openMobileMenu,
} from '~~/test/playwright/utils/navigation'

const mockUaString =
'Mozilla/5.0 (Android 7.0; Mobile; rv:54.0) Gecko/54.0 Firefox/54.0'
const mobileFixture = {
viewport: { width: 640, height: 700 },
userAgent: mockUaString,
}
test.use(mobileFixture)

test('Can open filters menu on mobile at least twice', async ({ page }) => {
await page.goto('/search/?q=cat')

await openFilters(page)
await expect(page.locator(`input[type="checkbox"]`)).toHaveCount(11, {
timeout: 100,
})
await closeMobileMenu(page)
await expect(page.locator(`input[type="checkbox"]`)).toHaveCount(0, {
timeout: 100,
})

await openFilters(page)
await expect(page.locator(`input[type="checkbox"]`)).toHaveCount(11, {
timeout: 100,
})
})

test('Can open mobile menu at least twice', async ({ page }) => {
await page.goto('/search/?q=cat')
await openMobileMenu(page)
await expect(page.locator('button', { hasText: 'Close' })).toBeVisible()
await closeMobileMenu(page)
await expect(page.locator('button', { hasText: 'Close' })).not.toBeVisible()
await openMobileMenu(page)
await expect(page.locator('button', { hasText: 'Close' })).toBeVisible()
})
45 changes: 38 additions & 7 deletions test/playwright/utils/navigation.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
import { expect, Page } from '@playwright/test'

export const openFilters = async (page: Page) => {
const filterButtonSelector = '[aria-controls="filters"]'
const isPressed = async () =>
await page.getAttribute(filterButtonSelector, 'aria-pressed')
if ((await isPressed()) !== 'true') {
await page.click(filterButtonSelector)
expect(await isPressed()).toEqual('true')
const buttonSelectors = {
filter: '[aria-controls="filters"]',
contentSwitcher: '[aria-controls="content-switcher-modal"]',
}

const isButtonPressed = async (page: Page, buttonSelector: string) => {
const viewportSize = page.viewportSize()
if (!viewportSize) {
return false
}
const pageWidth = viewportSize.width
if (pageWidth > 640) {
return await page.getAttribute(buttonSelector, 'aria-pressed')
} else {
return (await page.locator('button', { hasText: 'Close' }).isVisible())
? 'true'
: 'false'
}
}

const openMenu = async (page: Page, button: 'filter' | 'contentSwitcher') => {
const selector = buttonSelectors[button]
const expectedValue = 'true'
if ((await isButtonPressed(page, selector)) !== expectedValue) {
await page.click(selector)
expect(await isButtonPressed(page, selector)).toEqual(expectedValue)
}
}

export const openFilters = async (page: Page) => {
await openMenu(page, 'filter')
}

export const openMobileMenu = async (page: Page) => {
await openMenu(page, 'contentSwitcher')
}

export const closeMobileMenu = async (page: Page) => {
await page.click('text=Close')
}

export const assertCheckboxStatus = async (
page: Page,
label: string,
Expand Down

0 comments on commit 9c33844

Please sign in to comment.