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

Improve mocking dates/times in e2e tests #2942

Closed
rejas opened this issue Oct 11, 2022 · 12 comments
Closed

Improve mocking dates/times in e2e tests #2942

rejas opened this issue Oct 11, 2022 · 12 comments
Assignees

Comments

@rejas
Copy link
Collaborator

rejas commented Oct 11, 2022

Some module e2e tests need to fake a certain date/time to be run, especially the calendar module.

There isnt (yet) a general way to mock the current date/time in the e2e tests. Only hackish solutions exist, like for the compliments module for displaying a compliment on a specific date:

https://github.com/MichMich/MagicMirror/blob/a328ce537faf8d9b90d7eb2c09237fe83ae3a827/tests/e2e/modules/compliments_spec.js#L83

Here a mockDate is in the test config which gets read in the mm-js-logic. Using test logic in normal code is of course a no-no!

There are quite a few solutions out there, like sinon, mockDate or adding a jest.mock. Alas, the author hasnt gotten any of them to run for faking a test :-(

Adding the functionality to mock a certain date/time would open up a lot of new test posibilities, for example this new feature could be tested very easily.

@khassel
Copy link
Collaborator

khassel commented Oct 11, 2022

sample only with config.dir output:

describe("fake test date/time", () => {

        it("show date", () => {
                jest.useFakeTimers("modern");

                jest.setSystemTime(new Date("11 Oct 2022 00:12:00 GMT").getTime());

                console.dir(new Date());

                jest.useRealTimers();

                console.dir(new Date());
        });

});

Output:

node@1dbee275fa1b:/opt/magic_mirror$ npx jest tests/e2e/date_mock.js
  console.dir
    2022-10-11T00:12:00.000Z

      at Object.dir (tests/e2e/date_mock.js:8:11)

  console.dir
    2022-10-11T19:55:35.419Z

      at Object.dir (tests/e2e/date_mock.js:12:25)

 PASS   e2e  tests/e2e/date_mock.js
  fake test date/time
    ✓ show date (19 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.364 s
Ran all test suites matching /tests\/e2e\/date_mock.js/i.

Timezone can be set with process.env.TZ = "GMT"; or as offset as already done here.

Need we more?

@rejas
Copy link
Collaborator Author

rejas commented Oct 11, 2022

Looks like what we'd need, did you try to replace the mockDate construct in the mentioned compliments-test?

Need we more?

One gotta look through the code where it makes sense to test and fake dates/time to be sure :-)

@khassel
Copy link
Collaborator

khassel commented Oct 11, 2022

sounds like I should assign this to myself ;)

@khassel
Copy link
Collaborator

khassel commented Oct 11, 2022

are these your points in compliments tests?

  • mockDate is used in compliments.js, very ugly, so this should be removed
  • some tests run only within specific hours, should run every time and hour set as mock before

@rejas
Copy link
Collaborator Author

rejas commented Oct 11, 2022

I'll assign it to you :-)

@rejas
Copy link
Collaborator Author

rejas commented Oct 11, 2022

yes :-)

@khassel
Copy link
Collaborator

khassel commented Oct 12, 2022

the above mentioned jest.setSystemTime works for normal tests (unit) but not in our e2e test setup because the date/time of the browser has to be mocked. Found no solution for this.

Other possibility is to move such tests back to electron section because playwright can fake browser date/time.

Here a first (dirty) working example:

const { _electron: electron } = require("playwright");

let electronApp = null;
process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js";
process.env.TZ = "GMT";
jest.retryTimes(3);

describe("Compliments", () => {
	beforeEach(async () => {
		electronApp = await electron.launch({ args: ["js/electron.js"] });
	});

	afterEach(async () => {
		await electronApp.close();
	});

	it("Morning compliments for that part of day", async () => {
		expect(await electronApp.windows().length).toBe(1);
		const page = await electronApp.firstWindow();
		expect(await page.title()).toBe("MagicMirror²");
		expect(await page.isVisible("body")).toBe(true);
		page.evaluate(() => {
			Date.now = () => {
				return new Date("01 Oct 2022 10:00:00 GMT");
			};
		});
		let elem = page.locator(".compliments");
		await elem.waitFor();
		expect(elem).not.toBe(null);
		elem = page.locator(".module-content");
		await elem.waitFor();
		expect(elem).not.toBe(null);
		expect(["Hi", "Good Morning", "Morning test"]).toContain(await elem.textContent());
	});
});

@sdetweil
Copy link
Collaborator

sdetweil commented Oct 12, 2022

can't you set the date/time/tz from bash script between tests
https://www.cyberciti.biz/faq/howto-set-date-time-from-linux-command-prompt/

@khassel
Copy link
Collaborator

khassel commented Oct 12, 2022

may on my machine but I don't know if this would work when running the tests on github (can test it) but also no beautiful approach ...

@sdetweil
Copy link
Collaborator

yes, but the only other thing is to scaffold/proxy the calls made and during test return false info.. testing is SO much fun

rejas pushed a commit that referenced this issue Oct 17, 2022
first PR for #2942 

- added new electron tests for calendar which test new css classes from
#2939
- moved some compliments tests from `e2e` to `electron` because of date
mocking
- removed mock stuff from compliments module
@rejas
Copy link
Collaborator Author

rejas commented Oct 20, 2022

so we can close this now @khassel or do you think we can improve it even further? I am fine with the current state....

@khassel
Copy link
Collaborator

khassel commented Oct 20, 2022

can be closed, if we find more improvements we can do this in a new ticket.

@khassel khassel closed this as completed Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants