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

E2E Example #13

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

E2E Example #13

wants to merge 2 commits into from

Conversation

rperon
Copy link
Owner

@rperon rperon commented Mar 10, 2024

Test Plan

Checklist

  • Tests updated
  • Docs updated

Screenshots

@rperon rperon mentioned this pull request Mar 10, 2024
console.log(options)
const lng = options?.lng ?? 'en'
const instance = i18next.createInstance()
const i18nInit = instance.init({ ns: [lng], ...i18n, ...options })
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this slows the test a bit epicweb-dev/epic-stack#645 just enough to be significant on my 2019 16" mac with 8% disk space left

I am 90% sure we will have faster tests by initializing i18next in a global setup file https://playwright.dev/docs/test-global-setup-teardown#option-2-configure-globalsetup-and-globalteardown
and then calling createInstance on this i18n instance and passing the options to createInstance like so i18next.createInstance(options || undefined)

Indeed the benefit will be that we won't need to await the return of init function anymore in each test

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I tried global setup and project setup and that's the wrong approach. we could put the init before the await use, between line 102 and 103. It would be cleaner I think

  i18next: async ({}, use) => {
    const i18nextInstance = i18next;
    await i18nextInstance.use(initReactI18next).init({ ns: ['en'], ...i18nOptions })
    await use((options) => {
      return i18nextInstance.createInstance(options || undefined)
    })
  },
})

but that does not change the fact i18n will be initialized each time. Documentation says a fixture can be defined with a scope like so { scope: 'worker' } and that should be run once per browser session.. but I can't make it work

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up using the following which is performant

import commonENJson from '#app/translation/en.json' assert { type: 'json' }

export const test = base.extend<{
  ...
  t(key: string): string
}>({
  ...
  t: async ({}, use) => {
    await use((key: string) => {
      // @ts-expect-error -- let's allow dynamic keys
      return commonENJson?.[key]
    })
  },

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did the change where I put the i18next.createInstance() outside of the use function.
But with what you are proposing, are you able to test specific locale ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just put that function as an example. it only supports english. I personally do not care nor will spend testing time on my translations. waste of money and time at this point for my project

but you could of course change the signature of function t to for example update the lang when you call it the first time like t('en')('my.key)

import commonENJson from '#app/translation/en.json' assert { type: 'json' }
import commonFRJson from '#app/translation/fr.json' assert { type: 'json' }

const langs = {
  en: commonENJson,
  fr: commonFRJson
}

export const test = base.extend<{
  ...
  t(key: string): string
}>({
  ...
  t: async ({}, use) => {
    await use((lang: string) => (key: string) => {
      // @ts-expect-error -- let's allow dynamic keys
      return langs[lang]?.[key]
    })
  },

and you would use it like

test('description', async ({
  ...
  t,
}) => {
  await page
    .getByRole('button', {
      name: new RegExp(`${t('en')('auth.login.button.login')}$`, 'i'),
    })
    .click()

or if all your translations are in the same lang:

test('description', async ({
  ...
  t: tFunc,
}) => {
  const t = tFunc('en')
  await page
    .getByRole('button', {
      name: new RegExp(`${t('auth.login.button.login')}$`, 'i'),
    })
    .click()

@@ -16,6 +19,10 @@ afterEach(() => cleanup())

export let consoleError: SpyInstance<Parameters<(typeof console)['error']>>

// setup-test-env.ts

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this comment line 22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants