electron-playwright-helpers
Version:
Helper functions for Electron end-to-end testing using Playwright
171 lines • 6.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.stubDialog = stubDialog;
exports.stubMultipleDialogs = stubMultipleDialogs;
exports.stubAllDialogs = stubAllDialogs;
const utilities_1 = require("./utilities");
const dialogDefaults = {
showCertificateTrustDialog: undefined,
showErrorBox: undefined,
showMessageBox: {
response: 0,
checkboxChecked: false,
},
showMessageBoxSync: 0,
showOpenDialog: {
filePaths: [],
canceled: false,
},
showOpenDialogSync: [],
showSaveDialog: {
filePath: undefined,
canceled: false,
},
showSaveDialogSync: undefined,
};
/**
* Stub a single dialog method. This is a convenience function that calls `stubMultipleDialogs`
* for a single method.
*
* Playwright does not have a way to interact with Electron dialog windows,
* so this function allows you to substitute the dialog module's methods during your tests.
* By stubbing the dialog module, your Electron application will not display any dialog windows,
* and you can control the return value of the dialog methods. You're basically saying
* "when my application calls dialog.showOpenDialog, return this value instead". This allows you
* to test your application's behavior when the user selects a file, or cancels the dialog, etc.
*
* Note: Each dialog method can only be stubbed with one value at a time, so you will want to call
* `stubDialog` before each time that you expect your application to call the dialog method.
*
* @example
* ```ts
* await stubDialog(app, 'showOpenDialog', {
* filePaths: ['/path/to/file'],
* canceled: false,
* })
* await clickMenuItemById(app, 'open-file')
* // when time your application calls dialog.showOpenDialog,
* // it will return the value you specified
* ```
*
* @see stubMultipleDialogs
*
* @category Dialog
*
* @param app {ElectronApplication} The Playwright ElectronApplication instance.
* @param method {String} The [dialog method](https://www.electronjs.org/docs/latest/api/dialog#methods) to mock.
* @param value {ReturnType<Electron.Dialog>} The value that your application will receive when calling this dialog method.
* See the [Electron docs](https://www.electronjs.org/docs/latest/api/dialog#dialogshowopendialogbrowserwindow-options) for
* the return value of each method.
* @returns {Promise<void>} A promise that resolves when the mock is applied.
* @fullfil {void} - A promise that resolves when the mock is applied.
*
*/
function stubDialog(app, method, value) {
if (!value)
value = dialogDefaults[method];
return stubMultipleDialogs(app, [{ method, value }]);
}
/**
* Stub methods of the Electron dialog module.
*
* Playwright does not have a way to interact with Electron dialog windows,
* so this function allows you to mock the dialog module's methods during your tests.
* By mocking the dialog module, your Electron application will not display any dialog windows,
* and you can control the return value of the dialog methods. You're basically saying
* "when my application calls dialog.showOpenDialog, return this value instead". This allows you
* to test your application's behavior when the user selects a file, or cancels the dialog, etc.
*
* @example
* ```ts
* await stubMultipleDialogs(app, [
* {
* method: 'showOpenDialog',
* value: {
* filePaths: ['/path/to/file1', '/path/to/file2'],
* canceled: false,
* },
* },
* {
* method: 'showSaveDialog',
* value: {
* filePath: '/path/to/file',
* canceled: false,
* },
* },
* ])
* await clickMenuItemById(app, 'save-file')
* // when your application calls dialog.showSaveDialog,
* // it will return the value you specified
* ```
*
* @category Dialog
*
* @param app {ElectronApplication} The Playwright ElectronApplication instance.
* @param mocks {DialogMethodStubPartial[]} An array of dialog method mocks to apply.
* @returns {Promise<void>} A promise that resolves when the mocks are applied.
* @fullfil {void} - A promise that resolves when the mocks are applied.
*/
function stubMultipleDialogs(app, mocks) {
const mocksRequired = mocks.map((mock) => {
var _a;
const methodDefault = dialogDefaults[mock.method];
if (!methodDefault)
return mock;
if (typeof mock.value === 'object') {
mock.value = Object.assign({}, methodDefault, mock.value);
}
else {
mock.value = (_a = mock.value) !== null && _a !== void 0 ? _a : methodDefault;
}
return mock;
});
// idea from https://github.com/microsoft/playwright/issues/8278#issuecomment-1009957411 by @MikeJerred
return (0, utilities_1.retry)(() => app.evaluate(({ dialog }, mocks) => {
mocks.forEach((mock) => {
const thisDialog = dialog[mock.method];
if (!thisDialog) {
throw new Error(`can't find ${mock.method} on dialog module.`);
}
if (mock.method.endsWith('Sync')) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
dialog[mock.method] = () => {
// console.log(`Dialog.${v.method}(${args.join(', ')})`)
return mock.value;
};
}
else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
dialog[mock.method] = async () => {
// console.log(`Dialog.${v.method}(${args.join(', ')})`)
return mock.value;
};
}
});
}, mocksRequired));
}
/**
* Stub all dialog methods. This is a convenience function that calls `stubMultipleDialogs`
* for all dialog methods. This is useful if you want to ensure that dialogs are not displayed
* during your tests. However, you may want to use `stubDialog` or `stubMultipleDialogs` to
* control the return value of specific dialog methods (e.g. `showOpenDialog`) during your tests.
*
* @see stubDialog
*
* @category Dialog
*
* @param app {ElectronApplication} The Playwright ElectronApplication instance.
* @returns {Promise<void>} A promise that resolves when the mocks are applied.
* @fullfil {void} - A promise that resolves when the mocks are applied.
*/
function stubAllDialogs(app) {
// reformat the dialogDefaults object into the format that stubMultipleDialogs expects
const stubMultipleDialogsArgs = [];
for (const [method, value] of Object.entries(dialogDefaults)) {
stubMultipleDialogsArgs.push({ method, value });
}
return stubMultipleDialogs(app, stubMultipleDialogsArgs);
}
//# sourceMappingURL=dialog_helpers.js.map