Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update tests for Nuxt 3 migration #3667

Merged
merged 2 commits into from Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions frontend/src/components/VAudioTrack/VAudioControl.vue
Expand Up @@ -7,6 +7,7 @@
:icon-props="icon === undefined ? undefined : { name: icon, size: iSize }"
:label="$t(label)"
:connections="connections"
:disabled="!doneHydrating"
@click.stop.prevent="handleClick"
@mousedown="handleMouseDown"
>
Expand Down Expand Up @@ -43,6 +44,8 @@ import {
import { defineEvent } from "~/types/emits"
import type { ButtonConnections } from "~/types/button"

import { useHydrating } from "~/composables/use-hydrating"

import VIconButton from "~/components/VIconButton/VIconButton.vue"

const statusIconMap = {
Expand Down Expand Up @@ -157,6 +160,8 @@ export default defineComponent({
emit("toggle", isPlaying.value || isLoading.value ? "paused" : "playing")
}

const { doneHydrating } = useHydrating()

return {
label,
icon,
Expand All @@ -167,6 +172,7 @@ export default defineComponent({

handleClick,
handleMouseDown,
doneHydrating,
}
},
})
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/VContentLink/VContentLink.vue
Expand Up @@ -5,8 +5,8 @@
:aria-label="resultsAriaLabel"
variant="bordered-gray"
size="disabled"
:disabled="!doneHydrating"
class="h-auto w-full flex-col !items-start !justify-start gap-1 overflow-hidden p-4 sm:h-18 sm:flex-row sm:!items-center sm:gap-2 sm:px-6"
:send-external-link-click-event="false"
@keydown.native.shift.tab.exact="$emit('shift-tab', $event)"
@mousedown="handleClick"
>
Expand All @@ -33,6 +33,8 @@ import { defineEvent } from "~/types/emits"

import useSearchType from "~/composables/use-search-type"

import { useHydrating } from "~/composables/use-hydrating"

import VButton from "~/components/VButton.vue"
import VIcon from "~/components/VIcon/VIcon.vue"

Expand Down Expand Up @@ -95,11 +97,14 @@ export default defineComponent({
})
}

const { doneHydrating } = useHydrating()

return {
resultsCountLabel,
resultsAriaLabel,

handleClick,
doneHydrating,
}
},
})
Expand Down
Expand Up @@ -3,6 +3,7 @@
class="min-w-12 gap-x-2"
:class="showLabel ? '!px-3' : 'w-12'"
variant="bordered-white"
:disabled="!doneHydrating"
size="large"
:aria-label="$t('searchType.selectLabel', { type: label })"
v-bind="$attrs"
Expand All @@ -24,6 +25,8 @@ import { warn } from "~/utils/console"

import { defineEvent } from "~/types/emits"

import { useHydrating } from "~/composables/use-hydrating"

import VIcon from "~/components/VIcon/VIcon.vue"
import VButton from "~/components/VButton.vue"

Expand Down Expand Up @@ -63,6 +66,11 @@ export default defineComponent({
"You should provide `aria-haspopup` and `aria-expanded` props to VSearchTypeButton."
)
}
const { doneHydrating } = useHydrating()

return {
doneHydrating,
}
},
})
</script>
6 changes: 6 additions & 0 deletions frontend/src/components/VCopyButton.vue
Expand Up @@ -5,6 +5,7 @@
variant="filled-dark"
size="small"
class="label-bold flex-shrink-0"
:disabled="!doneHydrating"
:data-clipboard-target="el"
>
<span v-if="!success">
Expand All @@ -21,6 +22,8 @@ import Clipboard from "clipboard"

import { defineComponent, onBeforeUnmount, onMounted, ref } from "vue"

import { useHydrating } from "~/composables/use-hydrating"

import VButton from "~/components/VButton.vue"

export default defineComponent({
Expand Down Expand Up @@ -77,9 +80,12 @@ export default defineComponent({

onBeforeUnmount(() => clipboard.value?.destroy())

const { doneHydrating } = useHydrating()

return {
clipboard,
success,
doneHydrating,
}
},
})
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/VHeader/VHeaderInternal.vue
Expand Up @@ -17,6 +17,7 @@
ref="menuButtonRef"
variant="transparent-dark"
size="large"
:disabled="!doneHydrating"
:icon-props="{ name: 'menu' }"
:label="$t('header.aria.menu')"
v-bind="triggerA11yProps"
Expand Down Expand Up @@ -90,6 +91,7 @@ import { useRoute } from "@nuxtjs/composition-api"

import { useDialogControl } from "~/composables/use-dialog-control"
import { useAnalytics } from "~/composables/use-analytics"
import { useHydrating } from "~/composables/use-hydrating"
import usePages from "~/composables/use-pages"

import { useUiStore } from "~/stores/ui"
Expand Down Expand Up @@ -141,6 +143,8 @@ export default defineComponent({
() => modalContentRef.value?.deactivateFocusTrap
)

const { doneHydrating } = useHydrating()

const {
close: closePageMenu,
open: openPageMenu,
Expand Down Expand Up @@ -177,6 +181,7 @@ export default defineComponent({
currentPage,

isModalVisible,
doneHydrating,
closePageMenu,
openPageMenu,
isSm,
Expand Down
Expand Up @@ -81,6 +81,7 @@
:is-pressed="contentSettingsOpen"
:applied-filter-count="appliedFilterCount"
v-bind="triggerA11yProps"
:disabled="!doneHydrating"
@click="toggleContentSettings"
/>
<VContentSettingsModalContent
Expand Down Expand Up @@ -124,6 +125,8 @@ import { useSearch } from "~/composables/use-search"
import { useMediaStore } from "~/stores/media"
import { useSearchStore } from "~/stores/search"

import { useHydrating } from "~/composables/use-hydrating"

import VLogoButton from "~/components/VHeader/VLogoButton.vue"
import VInputModal from "~/components/VModal/VInputModal.vue"
import VContentSettingsModalContent from "~/components/VHeader/VHeaderMobile/VContentSettingsModalContent.vue"
Expand Down Expand Up @@ -292,6 +295,8 @@ export default defineComponent({
emit,
})

const { doneHydrating } = useHydrating()

return {
searchInputRef,
headerRef,
Expand All @@ -300,6 +305,7 @@ export default defineComponent({

appliedFilterCount,

doneHydrating,
contentSettingsOpen,
openContentSettings,
closeContentSettings,
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/components/VHeader/VSearchBar/VSearchButton.vue
Expand Up @@ -3,6 +3,7 @@
type="submit"
:aria-label="$t('search.search').toString()"
size="disabled"
:disabled="!doneHydrating"
variant="plain"
:class="[
'h-full flex-shrink-0 rounded-s-none border-s-0 p-0.5px ps-1.5px focus-slim-filled hover:text-white focus-visible:border-s group-focus-within:border-tx group-focus-within:bg-pink group-focus-within:text-white group-focus-within:hover:bg-dark-pink group-hover:border-tx group-hover:bg-pink group-hover:text-white',
Expand All @@ -20,6 +21,8 @@
<script lang="ts">
import { defineComponent, PropType } from "vue"

import { useHydrating } from "~/composables/use-hydrating"

import VIcon from "~/components/VIcon/VIcon.vue"
import VButton from "~/components/VButton.vue"
/**
Expand All @@ -37,5 +40,12 @@ export default defineComponent({
required: true,
},
},
setup() {
const { doneHydrating } = useHydrating()

return {
doneHydrating,
}
},
})
</script>
18 changes: 18 additions & 0 deletions frontend/src/composables/use-hydrating.ts
@@ -0,0 +1,18 @@
import { nextTick, onMounted, ref } from "vue"

/**
* Composable used to set interactive elements disabled until the hydration is done.
* @see https://playwright.dev/docs/navigations#hydration
*/
export const useHydrating = () => {
const doneHydrating = ref(false)
onMounted(() => {
nextTick().then(() => {
doneHydrating.value = true
})
})

return {
doneHydrating,
}
}
13 changes: 2 additions & 11 deletions frontend/src/middleware/middleware.ts
Expand Up @@ -2,8 +2,6 @@ import { useProviderStore } from "~/stores/provider"
import { useFeatureFlagStore } from "~/stores/feature-flag"
import { useUiStore } from "~/stores/ui"

import { cookieOptions } from "~/utils/cookies"

import type { Context, Middleware } from "@nuxt/types"

/**
Expand All @@ -19,12 +17,7 @@ import type { Context, Middleware } from "@nuxt/types"
* Currently, one event type is used:
* - `urlChange` sends the relative path of the URL on every URL change.
*/
const middleware: Middleware = async ({
$cookies,
$ua,
query,
$pinia,
}: Context) => {
const middleware: Middleware = async ({ $cookies, query, $pinia }: Context) => {
/* Provider store */
const providerStore = useProviderStore($pinia)
await providerStore.fetchMediaProviders()
Expand All @@ -39,9 +32,7 @@ const middleware: Middleware = async ({
/* UI store */

const uiStore = useUiStore($pinia)
const isMobileUa = $ua ? $ua.isMobile : false

$cookies.set("uiIsMobileUa", isMobileUa, cookieOptions)
uiStore.initFromCookies($cookies.getAll() ?? {})
uiStore.initFromCookies($cookies.get("ui") ?? {})
}
export default middleware