13

I can't figure out how to set a timezone when using Chromedriver. Is there some ChromeOptions argument or something?

The issue is that when I go to some sites (for example, https://whoer.net), it shows the system time that is equal to the time set on Windows. And I want to be able to change the Chromedriver's timezone somehow to perform timezone dependent testing.

I tried to set some chrome options:

Map<String, Object> chromeOptions = new HashMap<String, Object>();
chromeOptions.put("args", Arrays.asList("--disable-system-timezone-automatic-detection", "--local-timezone"));
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);

It doesn't work.

Tried to do some weird thing using Javascript:

((JavascriptExecutor) driver).executeScript("Date.prototype.getTime = function() { return 1 };");
   

It didn't help either.

EDIT:

Found this https://sqa.stackexchange.com/questions/8838/faking-system-time-date-with-selenium-webdriver

Tried to execute javascript on page with the code copied from TimeShift.js like this:

((JavascriptExecutor) driver).executeScript("/*code from TimeShift.js here*/ TimeShift.setTimezoneOffset(-60);");

System time at https://whoer.net didn't change. What am I doing wrong?

Helen
  • 347
  • 1
  • 4
  • 16
  • It will always show the time set on Windows. Change the time on Windows. – Elliott Frisch Jun 22 '17 at 00:28
  • Maybe this similiar question can help you https://stackoverflow.com/questions/35848043/selenium-scraping-changing-timezone – Pv-Viana Jun 22 '17 at 00:31
  • @Pv-Viana In that question he is scraping a timezone from some site and then he can choose the desired timezone from the site's menu. It's different. – Helen Jun 22 '17 at 00:46
  • @ElliottFrisch I know I can change the time on Windows, even can do it in java code: `Runtime.getRuntime().exec("cmd /C time " + "16:56:10");` but this option isn't good for me since I want to perform a multithreaded test with many instances of Chromedriver at the same time and I want each instance to have it's own system time. – Helen Jun 22 '17 at 00:49
  • @JeffC Ok, edited the question. – Helen Jun 22 '17 at 01:13
  • Does the application get time from local Windows or server? – Buaban Jun 22 '17 at 02:07
  • @Buaban I want the application to get the time from the proxy's ip and I want the browser to think it's the system time – Helen Jun 22 '17 at 02:26
  • I believe you cannot wish the application to get time from other sources because the code to get time is in the application. You need to know where does it get time from. – Buaban Jun 22 '17 at 02:29
  • @Buaban If you are talking about my java application that uses Chromedriver, of course, I can do something with system time in the application. The problem is with the driver, when my application launches Chromedriver (and I see the browser), the problem is that the browser takes system time from my OS. I thought there is some way to say the browser (via some arguments or preferences etc.) not to take system time from Windows. Or to mock system time via executing javascript at the page which is loaded in the browser. But all the methods to do so don't work. – Helen Jun 22 '17 at 06:02
  • Sorry, I'm talking about the web application. If the web application uses JavaScript to get current datetime or timezone, JS will be executed by JS engine in the browser. The browser will get it from OS. You have to inject some code to shift time after the page load and before the date object has been initialized. – Buaban Jun 22 '17 at 06:20
  • @Buaban I tried to do it like this: `var dateYouWant = 1363798981693; Date.prototype.getTime = function() { return dateYouWant; }; console.log( (new Date).getTime() );` and like this `var d = new Date(2012, 0, 20); Date = undefined; Date = function(){return d;}` but no luck, I keep seeing my Windows time at http://whoer.net. These methods supposed to work, I don't understand why they don't. Also tried to inject these pieces of code via Javascript Injector Google Chrome addon in the normal Google Chrome (not Chromedriver), no luck too. – Helen Jun 22 '17 at 06:35

4 Answers4

9

You can do it by using Chrome DevTools Protocol, and here is the python code:

driver = webdriver.Chrome()
tz_params = {'timezoneId': 'America/New_York'}
driver.execute_cdp_cmd('Emulation.setTimezoneOverride', tz_params)
Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
garrythehotdog
  • 191
  • 1
  • 3
7

with new selenium 4, it can be done natively with CDP

    WebDriverManager.chromedriver().setup();
    WebDriver driver = new ChromeDriver();
    DevTools devTools = ((ChromeDriver) driver).getDevTools();
    devTools.createSession();
    devTools.send(Emulation.setTimezoneOverride("Antarctica/Casey"));

download the following maven dependency:

      <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.0.0-alpha-6</version>
    </dependency>

list of time zones can be found here

Nir Tal
  • 309
  • 1
  • 4
  • 15
4

As far as I know you can only do this with TZ variable or with Decker Selenium.

Were you able to find a viable solution to this however? I am trying to do the same exact thing and have found very little in the way of solutions. I'm trying to do it with Python. The Tz variable solution is limited to Firefox in windows and decker selenium is a nightmare to install on windows.

UPDATED PYTHON SOLUTION VIABLE (below)

os.environ["DEBUSSY"] = "1"

SEE: How to set environment variables in Python

I am not sure if there is a Java equivalent but this Python equivalent worked for me in windows but only in Firefox. If you find a Java equivalent then that's awesome but if this issue is important to you Python is the way to go! :). I believe you are limited to three letters in windows but full customisation in Linux operating systems. E.g UTC, GMT etc, etc,. Hope this was helpful to you. I spent ages looking for this but turns out I was overthinking it. Good luck!!

  • 1
    Unfortunately, I didn't find a way to do it and I have the same info as you. I'm thinking about trying Docker, but I didn't try it yet. I'm trying to do it with Java. If I find a way, I'll share it here. – Helen Sep 07 '17 at 07:10
  • @Helen Ive updated my answer, there is an easy and viable way to do this with Python. For Java, I don't know how. If you had to do it you would have to do it through command line. So in windows it would be: set TZ=UTC-4. And then you'd have to launch chromedriver after you have set it. Or something like that. :) –  Sep 08 '17 at 07:52
  • 1
    Unfortunately I need to do it with Chrome, not Firefox :) And Chrome doesn't recognize TZ variable if you run it on Windows. But thank you anyway @JayRen – Helen Sep 09 '17 at 08:54
  • 1
    @Helen Oh right sorry about that but that to my knowledge is simply unachievable on Windows. Firefox is your next bet as it has way more privacy options. Maybe possible on Linux though. Not really sure. Well I hope you find your solution this solved my problem. –  Sep 09 '17 at 11:12
  • 3
    In docker you can set TZ variable: `docker run -d selenium/hub -e "TZ=US/Pacific"...` [link here](https://github.com/SeleniumHQ/docker-selenium/wiki/Setting-a-Timezone) – michael Apr 11 '19 at 09:19
0

Setting timezone to existing browser window is not a good idea by design:

  1. Browser proxy ip address should be set on start.
  2. Browser session starts on start (and may be restored before start).
  3. Apropriate environment including timezone, user agent, etc should be resolved on start for proxy ip.

So i am proposing the following solution:

  1. Find proxy ip that you want to use, geolocate it.
  2. Restore existing browser session from database by proxy ip.
  3. Use apropriate environment (timezone, user agent, etc) for proxy ip.

For example:

TZ="Asia/Shanghai" chromium --user-data-dir=".." --proxy-server=".." 

It works fine.

PS you need to patch your local chromium to use required environment parts like predefined user agent.

puchu
  • 3,294
  • 6
  • 38
  • 62