Cypress: Accept locale as configuration

Created on 6 Jul 2020  路  4Comments  路  Source: cypress-io/cypress

First of all: thank you for your work on Cypress 馃檹. It's awesome and such a pleasure to use!


Current behavior:

I have no unified, platform-independent way of controlling the browser locale. Setting it is specific to the browser and platform and thus error prone.

Desired behavior:

My goal is to get a predictable output of new Intl.DateTimeFormat().resolvedOptions(). I'm on macOS and I haven't found a way to set the browser locale in Chrome. It always resolves to locale: "en-GB" but it should resolve to en-US. I tried setting the LANGUAGE, LANG, LC_ALL environment variables but it seems like they are ignored or overwritten. I also tried the --lang argument but that doesn't work as well (I read that it's only supported on Windows).

I also tried setting

  • launchOptions.preferences.default["settings.language.preferred_languages"]
  • launchOptions.preferences.default["intl.initial_locale"]
  • launchOptions.preferences.localState["variations_safe_seed_locale"]

during 'before:browser:launch' but with no luck.

To be honest, I didn't even get Chrome to start from the command line with the correct locale. I tried it with this command:

LANGUAGE=en-US LANG=en-US LC_ALL=en-US ./"Google Chrome" --user-data-dir="~/temp" --lang="en"

So this is probably also kind of a Chrome issue.

I saw that Cypress is using a dedicated user profile located in ~/Library/Application Support/Cypress/cy/production/browsers/chrome-stable/interactive/Default. Maybe it needs to be set somewhere there...

In this issue I'm asking for two things:

  • In case you know a way how to set the Chrome locale or even in case you know that this is still an unsolved issue, could you please document this in this issue? I think this could be a common problem since a lot of web developers are on macOS.

  • It would be nice if Cypress offered an easy, cross-platform configuration for setting the browser locale. There is a similar request for the timezone and I think this is quite common: you want to control the locale and the timezone your tests are executed with. (Btw: setting the TZ env variable works fine).

Test code to reproduce

Versions

proposal 馃挕 feature

Most helpful comment

The Chrome DevTools team recently added the possibility to change this via the "Sensors" tab in the DevTools. They also expose this as experimental API to the Chrome DevTools Protocol. There is:

I was able to set the locale and the timezone in my tests with this snippet:

it("should set the expected locale and timezone", () => {
  return Cypress.automation("remote:debugger:protocol", {
    command: "Emulation.setLocaleOverride",
    params: {
      locale: "de-AT",
    },
  })
    .then(() => {
      return Cypress.automation("remote:debugger:protocol", {
        command: "Emulation.setTimezoneOverride",
        params: {
          timezoneId: "Pacific/Fiji",
        },
      });
    })
    .then(() => {
      const { locale, timeZone } = new Intl.DateTimeFormat().resolvedOptions();

      console.log(locale, timeZone); // Logs 'de-AT' and 'Pacific/Fiji'
    });
});

Working example: https://github.com/jhnns/cypress-test-tiny/blob/locale-fix/cypress/integration/spec.js

So this is a nice workaround. But it seems like Cypress.automation("remote:debugger:protocol" is an internal API since it's not officially documented. It would be awesome if I could either configure it via the cypress.json or even change it on runtime by calling a command.

All 4 comments

Yeah, I'm not sure of a way to set this exactly. Tried a few things as well and was unable to change the locale.

The Chrome DevTools team recently added the possibility to change this via the "Sensors" tab in the DevTools. They also expose this as experimental API to the Chrome DevTools Protocol. There is:

I was able to set the locale and the timezone in my tests with this snippet:

it("should set the expected locale and timezone", () => {
  return Cypress.automation("remote:debugger:protocol", {
    command: "Emulation.setLocaleOverride",
    params: {
      locale: "de-AT",
    },
  })
    .then(() => {
      return Cypress.automation("remote:debugger:protocol", {
        command: "Emulation.setTimezoneOverride",
        params: {
          timezoneId: "Pacific/Fiji",
        },
      });
    })
    .then(() => {
      const { locale, timeZone } = new Intl.DateTimeFormat().resolvedOptions();

      console.log(locale, timeZone); // Logs 'de-AT' and 'Pacific/Fiji'
    });
});

Working example: https://github.com/jhnns/cypress-test-tiny/blob/locale-fix/cypress/integration/spec.js

So this is a nice workaround. But it seems like Cypress.automation("remote:debugger:protocol" is an internal API since it's not officially documented. It would be awesome if I could either configure it via the cypress.json or even change it on runtime by calling a command.

Yeah, passing things to the Chrome DevTools Protocol is not officially documented. I'm going to check with the team on what our plans were for exposing/documenting this because I've seen some other people tap into it as well.

Will leave this issue open for a more easily configurable way to set locale.

Hello friends!

The Chrome DevTools team recently added the possibility to change this via the "Sensors" tab in the DevTools. They also expose this as experimental API to the Chrome DevTools Protocol. There is:

I was able to set the locale and the timezone in my tests with this snippet:

it("should set the expected locale and timezone", () => {
  return Cypress.automation("remote:debugger:protocol", {
    command: "Emulation.setLocaleOverride",
    params: {
      locale: "de-AT",
    },
  })
    .then(() => {
      return Cypress.automation("remote:debugger:protocol", {
        command: "Emulation.setTimezoneOverride",
        params: {
          timezoneId: "Pacific/Fiji",
        },
      });
    })
    .then(() => {
      const { locale, timeZone } = new Intl.DateTimeFormat().resolvedOptions();

      console.log(locale, timeZone); // Logs 'de-AT' and 'Pacific/Fiji'
    });
});

Working example: https://github.com/jhnns/cypress-test-tiny/blob/locale-fix/cypress/integration/spec.js

So this is a nice workaround. But it seems like Cypress.automation("remote:debugger:protocol" is an internal API since it's not officially documented. It would be awesome if I could either configure it via the cypress.json or even change it on runtime by calling a command.

This solution dont work for me =/

This is my solution for the problem, enjoy!

describe('Detect browser language', () => {
  it('when browser language is english', () => {
    cy.visit('http://localhost:3000', {
      onBeforeLoad(win) { // solution is here
        Object.defineProperty(win.navigator, 'languages', {
          value: ['en-US'],
        });
      },
    });

    cy.contains('Welcome to react using react-i18next');
  });

  it('when browser language is german', () => {
    cy.visit('http://localhost:3000', {
      onBeforeLoad(win) { // solution is here
        Object.defineProperty(win.navigator, 'languages', {
          value: ['de-DE'],
        });
      },
    });

    cy.contains('Willkommen, um mit react-i18next zu reagieren');
  });
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

egucciar picture egucciar  路  3Comments

brian-mann picture brian-mann  路  3Comments

jennifer-shehane picture jennifer-shehane  路  3Comments

igorpavlov picture igorpavlov  路  3Comments

jennifer-shehane picture jennifer-shehane  路  3Comments