Mock current time or freeze date/time in WDIO - javascript

I am writing a test in WebDriverIO, where age is calculated dynamically. This creates issue as snapshot updates every month with new age value and build fails. Is there any way to mock or freeze current date/time, which will not update the age?
I tried updating DOM elements which did not work, as they are not user editable.

Related

Is there a way to get the actual time in UST (ignoring user settings) in React Native?

I'm currently working on a bug where the user manually sets their timezone and then manually sets the time within that timezone (say, 3 hours behind). This causes the system to use the user's time (which is 3 hours behind UST). Due to this, any calls to a Javascript or React Native library will return a time that is 3 hours behind the actual time. This causes issues when dealing with API calls to my server which returns the actual time in UST
I've tried using Date objects, the I18n library, and just about everything in between. I'm trying to find a universal fix for both Android and iOS since this is a part of my cross-platform codebase.
Any help would be greatly appreciated!
The libraries get the time from the client, how about getting the time from an external source? You can use this API: https://timezonedb.com/api
Another possibility is storing and updating a time offset, so you can calculate the actual time from the current time that is set.

Change the timezone from windows on the fly using protractor

I am facing some challenges to find a better way to test timezones, what is happening now is:
I have a report with some links (for detailed data), when the user access this report comes the transaction date as one of the columns (lets say its today 11th)
When the user clicks at one of these links to have more details about the transaction, the user is transferred to the detail page.
The bug is, when the timezone is UTC-04 the user gets the date of 10th instead of 11th, it only works properly with the UTC+2
I have tried to mock the change of timezone using this:
https://www.npmjs.com/package/timezone-mock
But didn't work as I wanted, the date is changed but the bug doesn't happen.
It is possible to reproduce this only when I change manually the timezone from windows.
I also found the possibility of using powershell commands to do this
Setting timezone in Protractor e2e tests
https://www.npmjs.com/package/node-powershell
So far I could not make it work.
The question is, is it possible to automate the change of window's (system) timezone somehow?
Ty!
So, after some time trying and failing.. found this:
https://support.microsoft.com/en-us/help/2556308/tzutil-command-line-tool-is-added-to-windows-vista-and-to-windows-serv
tzutil.exe works for windows 10 and windows server as well, it is really simple to execute, the function needs to be like this:
browser.controlFlow().execute(() => {
var child_process = require('child_process');
console.log(String(child_process.exec('tzutil /s "Eastern Standard Time')));
});
This changes automatically the timezone from the system.

how to invoke various goog.i18n.TimeZone Instance Methods in my javascript file?

In order to invoke various instance methods of goog.i18n.TimeZone, I've tried pretty good number of combinations of goog.require() and goog.inherits() but still didn't reach the goal. Please can someone let me know what should be the correct way to do that?
Already done with Google Closure Library documentations. So it would be helpful if a demonstration with "Example.js" is shown.
I've found one of the best ways to learn the closure library is to look at the unit tests with-in
the library itself. If you haven't already done so, clone "https://github.com/google/closure-library/". You can then look in: "https://github.com/google/closure-library/blob/master/closure/goog/i18n/timezone_test.js". Look for any of the
unit test methods in the test class that match your use-case. For example, simple time zone:
function testSimpleTimeZoneZero() {
var date = new Date();
var simpleTimeZone = goog.i18n.TimeZone.createTimeZone(0);
assertEquals(0, simpleTimeZone.getOffset(date));
assertEquals('GMT+00:00', simpleTimeZone.getGMTString(date));
assertEquals('Etc/GMT', simpleTimeZone.getTimeZoneId());
assertEquals('UTC', simpleTimeZone.getLongName(date));
assertEquals('UTC', simpleTimeZone.getShortName(date));
assertEquals('+0000', simpleTimeZone.getRFCTimeZoneString(date));
assertEquals(false, simpleTimeZone.isDaylightTime(date));
}
The other aspect of the timezone class you must be aware of is that it required "data" to operate.
from the documentation "https://google.github.io/closure-library/api/goog.i18n.TimeZone.html":
i18n.TimeZone Extends
TimeZone class implemented a time zone resolution and name information source for client applications. The time zone object is initiated from a time zone information object. Application can initiate a time zone statically, or it may choose to initiate from a data obtained from server. Each time zone information array is small, but the whole set of data is too much for client application to download. If end user is allowed to change time zone setting, dynamic retrieval should be the method to use. In case only time zone offset is known, there is a decent fallback that only use the time zone offset to create a TimeZone object. A whole set of time zone information array was available under http://go/js_locale_data. It is generated based on CLDR/ICU and Olson time zone data base, and will be updated timely.
The unit test shows a mechanism to "load" this data statically (at the top of the file).

Is Javascript's Date object dependent on the user's browser?

I just realized that using Javascript's Date object to get the date may return different results depending on the user's browser/computer. Is this the case or does Javascript somehow always returns the actual time, regardless of the user's computer's settings?
Yes, it returns Date as per Users System date:
The Date object enables the JavaScript developer to create a Date
object initialized to a specific time and date, or to create a date
object that reflects the current system time on the computer on which
the browser is running. There are two important things to note when
working with the JavaScript Date object. Firstly, when reading the
date and time of the user's computer you are completely at the mercy
of the user's ability to set and maintain the correct day and time on
their computer. Secondly, whilst you can read the system date and time
set on the user's computer, and change those settings within your Date
object instance, you cannot change the computer's system date and
time. No matter what methods you call or properties you change on your
Date object, the user's system date and time remain unaltered.
http://www.techotopia.com/index.php/JavaScript_Date_Object
Yes. Javascript (generally) runs on the Client side. Anything it does will likely be relative to the clients machine. In this case, the system clock (not the browser AFAIK)
Yes it is entirely dependent on the user's local system time.
If you want to work with the server time, you can always populate the date object with some server side code that prints the current server time.
Different browser implementations should support standard Date object requirements, but some have bugs and some have taken the capabilities further than others. Current time taken from the computer's system time is of course out of your control. Take a look at moments.js. It's a nice little library that deals with such intricacies that you do have control over.
A 5.5kb javascript date library for parsing, validating, manipulating,
and formatting dates.

Need workaround for Firefox Date() bug

I'm working on a canvas graph that's updated in real time with information we're displaying to a customer, and were in the process of preparing for the DST change on the clocks. One of our requirements is for the graph to carry on functioning as usual without the need for the customer to refresh the page when the clocks switch over.
While working on this problem, I found out about this bug with Firefox:
https://bugzilla.mozilla.org/show_bug.cgi?id=127246
Basically the Date() object in JavaScript doesn't update in Firefox if the system time is changed without having to close the browser/tab, and as we're querying an API using the system clock, this is a pretty major problem.
I'm assuming it's not fixed as the ticket is still marked as 'NEW', and I'm also pretty sure it's this that's causing the problem rather than another part of my code, so how can i get the current time of the system clock after it changes in Firefox without having to refresh the page?
FYI the version of Firefox I'm using is 19.0.2
Thanks in advance
Example
Set system clock to 12:00 and open web app...
var currentHour = new Date().getHours() //returns 12
Set system clock to 13:00 without reopening web app..
var currentHour = new Date().getHours() //returns 12
You can't ever rely on the client-side to have the correct date/time set anyway. The only workaround I can think of is to request the current time from another source, e.g. the server.
If you don't want to bug your own server you could find a public API that returns a timestamp, like some kind of Time API, or a service with reliable uptime such as eBay's Client Alerts API for instance:
http://clientalerts.ebay.com/ws/ecasvc/ClientAlerts?callbackname=hello&callname=GetPublicAlerts
hello({"Timestamp":"2013-03-22T14:43:21.757Z","Ack":"Failure","Errors":[{"ShortMessage":"Missing required input element.","LongMessage":"Required input element is missing from the request.","ErrorCode":"1.19","SeverityCode":"Error","ErrorParameters":[{"Value":"ChannelDescriptor","ParamID":"0"}],"ErrorClassification":"RequestError"}],"Build":"E809_CORE_BUNDLED_15739296_R1","Version":"809"});
Ignore everything and just get the UTC timestamp. Just make sure you're not bashing the hell out of some server for data you don't really need!
Use Web Workers
Instead of creating a new window as in Sergiu Toarca's answer, create a new web worker every time you need an update. Firefox would update the Date() object whenever a new web worker is generated.
function currDate() {
var blob = new Blob([""]),
blobURL = window.URL ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob),
worker = new Worker(blobURL);
worker.terminate();
return new Date();
}
You can use it like a normal Date() object:
currDate().getHours(); // Gives you an updated hour
See DEMO (Works on Firefox 19).
There is a simple (but very hacky) workaround for this problem. You can create a new window (which for some reason resets the cache of the current window), get the date from there, and then immediately close the window.
var getRealDate = function() {
var w = window.open();
var ret = new Date();
w.close();
return ret;
};
See it work on jsfiddle. Click the button, then change your timezone, then click the button again, and you will get an updated value.
Note: Only tested in Firefox 19
As you are talking about real-time updates of the canvas I assume that you are using some kind of push technology, such as making use of web sockets, or some fake push technology such as AJAX long polling.
However, as you can not rely on the client-side time anyway (as was mentioned in the other answer), why not just use your real-time push data packages to include the current time?
This way you can kill two birds with one stone (sorry for the martial expression, but that's how they say ;-)):
You have one central clock you can rely on: Your server.
You make use of your existing data update infrastructure and do not need something else on top.
Clients can set their clocks to whatever they want, they will always the correct data.
All your clients need to do is to get the timezone they are in initially, and then add or subtract the difference to the timezone that is being delivered by the server. E.g., if your client is on UTC+1 and your server is UTC+4, then simply subtract 3 hours from each timestamp your server delivers.
As DST changes only appear twice a year, you can even hard-code this into your client and use two different addition / subtraction algorithms. Which one you have to use you can decide depending on the date part of the time stamp the server sends to you.
This way you should have solved all your problems, it works in every browser, and is independent of any time settings of the client.
Hope this helps :-)
Here's a super-simple solution for the OP's specific situation, given that the following assumptions I've made (based on what's written in his question and comments) are correct:
the graph is only for one customer
the graph will be loaded primarily on Firefox (versions that have the same referenced bug)
the customer's machine(s) is/are all based in GMT (which becomes BST when the clocks change)
the machine clock(s) is/are reasonably accurate
the customer doesn't go changing the machines' clocks will-nilly.
If the above are true (possibly not even all of them), this becomes pretty simple. Because you'd really only be worried about two time zones, GMT and BST, you can adapt your example as follows:
Add this bit of code at load time / graph initialization:
// given a date object, returns the actual hour (works for GMT/BST only)
var getDisplayHour = (function() {
var initiallyGMT = (new Date().toString().indexOf('BST') === -1);
return function ( date ) {
var isGMT = (date.toString().indexOf('BST') === -1);
var offset = initiallyGMT - isGMT;
return date.getHours() + offset;
}
})();
Set system clock to 12:00 and open web app...
var currentDisplayHour = getDisplayHour( new Date() ); // returns 12
Set system clock to 13:00 without reopening web app..
// the referenced bug keeps the same time, but it successfully changes the time zone, so:
var currentDisplayHour = getDisplayHour( new Date() ); // returns 13
Tested on FF 19.0.0.2 on Mac and Windows 7.
Note: Since I wasn't really able to reproduce the OP's issue, and considering the cited use case, I'm not even sure there's a need for any of these workarounds at all. One might expect a more accurate test for the OP's use case to involve changing both the time AND the zone. E.g. not just 12:00 -> 13:00, but 12:00 GMT -> 13:00 BST. An even more accurate simulation of the DST changeover would be to set the clock to 2013-03-31 00:59:00 GMT, check the new Date().getHours(), wait a couple minutes, and then to check the hour again.
But, as I said, I haven't been able to reproduce the cited bug this myself, so I could definitely be wrong (in which case I'll amend or remove this answer).
Hope this helps, anyway!

Categories