-
Notifications
You must be signed in to change notification settings - Fork 283
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
Backend code for quitOnClose
option
#3843
Backend code for quitOnClose
option
#3843
Conversation
861193c
to
0c6a9f8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few lint issues found by CI as well.
e2e/quit-on-close.e2e.spec.ts
Outdated
await sleep(waitTime); | ||
const browserWindowHandle = await electronApp.browserWindow(page); | ||
browserWindowHandle.evaluate((browserWindow: Electron.BrowserWindow) => browserWindow.close()); | ||
await sleep(waitTime); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we're waiting for the shutdown to complete? Since the CI machines are randomly slow, it would be good if there's something we could actually poll for (which would let us have a much longer maximum wait time, and finish much sooner on average).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to get something like this working, but haven't been able to. The way I've tried is to listen to the quit
event on Electron.app
, and set a variable when the event fires:
test('should quit when quitOnClose is true and window is closed', async() => {
createDefaultSettings({ window: { quitOnClose: true } });
const {electronApp, page} = await startRancherDesktop(__filename);
const browserWindowHandle = await electronApp.browserWindow(page);
let hasQuit = false;
electronApp.evaluate(({app}) => {
app.on('quit', () => {
console.log('quit event occurred')
hasQuit = true;
});
});
browserWindowHandle.evaluate((browserWindow: Electron.BrowserWindow) => browserWindow.close());
const sleepTime = 5000;
const iterCount = 6;
for (let i = 0; i < iterCount; i++) {
console.log(`hasQuit: ${ hasQuit }`)
if (hasQuit) {
return;
}
await sleep(sleepTime)
}
// fail the test if RD has not quit by now
expect(true).toBe(false);
});
But it doesn't seem to work. I'm not very confident with playwright though. Maybe you can see something I'm doing wrong? Or maybe you're away of another way of doing it? I can't think of anything else...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe .evaluate
works something like serializing the function to text, and eval()
it on the other side. So in your case, hasQuit
isn't getting a closure, so it's never set to true on the test side.
In my case, I do everything within evaluate()
, and it only returns a Promise<boolean>
which the documentation says it can.
0c6a9f8
to
daba531
Compare
Signed-off-by: Adam Pickering <[email protected]>
daba531
to
3ba5abb
Compare
I can't get the e2e test to start running on both linux and mac |
40773ac
to
c159bcb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works fine for me on mac & Windows, and CI (running Linux) look fine with it too.
* @param testPath The path to the test file. | ||
*/ | ||
export async function startRancherDesktop(testPath: string): Promise<{electronApp: ElectronApplication, page: Page}> { | ||
const electronApp = await _electron.launch({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we call await electronApp.context.tracing.start({ screenshots: true, snapshots: true });
somewhere in this function?
e2e/quit-on-close.e2e.spec.ts
Outdated
}); | ||
}); | ||
|
||
async function pollForQuit(electronApp: ElectronApplication): Promise<boolean> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works fine, but has a minimum run time of 30s (for the case where we don't want to quit).
Possible alternate, but I'm not sure I've got enough of a wait in:
function closeAllWindows(electronApp: ElectronApplication): Promise<boolean> {
return electronApp.evaluate(async({ app, BrowserWindow }) => {
const quitReady = new Promise<boolean>((resolve) => {
app.on('will-quit', () => resolve(true));
app.on('window-all-closed', () => {
setTimeout(() => resolve(false), 1_000);
});
});
await Promise.all(BrowserWindow.getAllWindows().map((window) => {
return new Promise<void>((resolve) => {
window.on('closed', resolve);
window.close();
});
}));
return await quitReady;
});
}
…
test('should quit when quitOnClose is true and window is closed', async() => {
createDefaultSettings({ window: { quitOnClose: true } });
const { electronApp } = await startRancherDesktop(__filename);
await expect(closeAllWindows(electronApp)).resolves.toBe(true);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a better way to do it. I have to say though, I'm confused as to why my use of electronApp.evaluate
above doesn't work, whereas its use here does. Can you not refer to a variable from an outer scope or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above — yeah, I think evaluate()
is really serialize-and-eval()
, so closures wouldn't work. This is why in my implementation all of the work happens inside the evaluate()
call (in the Electron process), and only a boolean is returned to the test process.
0f13f16
to
622cf9a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty happy with it, just some nits.
@@ -6,7 +6,7 @@ import os from 'os'; | |||
import path from 'path'; | |||
import util from 'util'; | |||
|
|||
import { ElectronApplication, expect } from '@playwright/test'; | |||
import { expect, _electron, ElectronApplication, Page } from '@playwright/test'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, ElectronApplication
and Page
can be changed to an import type
, but that's mostly just moving deck chairs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's alright, I'd like to keep it as it is. The following link is convincing to me: microsoft/TypeScript#39861
Signed-off-by: Adam Pickering <[email protected]>
622cf9a
to
c9e68a8
Compare
e2e tests pass now on my machines |
Closes #3261.