mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-04 14:03:27 +00:00 
			
		
		
		
	tests: Migrate E2E tests to Playwright.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
		
							
								
								
									
										1229
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1229
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -176,10 +176,11 @@
 | 
			
		||||
    "electron-notarize": "^1.0.0",
 | 
			
		||||
    "eslint-import-resolver-typescript": "^2.4.0",
 | 
			
		||||
    "htmlhint": "^0.15.1",
 | 
			
		||||
    "medium": "^1.2.0",
 | 
			
		||||
    "playwright-core": "^1.16.3",
 | 
			
		||||
    "pre-commit": "^1.2.2",
 | 
			
		||||
    "prettier": "^2.3.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
    "spectron": "^15.0.0",
 | 
			
		||||
    "stylelint": "^13.13.1",
 | 
			
		||||
    "stylelint-config-prettier": "^8.0.2",
 | 
			
		||||
    "stylelint-config-standard": "^22.0.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
const {chan, put, take} = require("medium");
 | 
			
		||||
const test = require("tape");
 | 
			
		||||
 | 
			
		||||
const setup = require("./setup.js");
 | 
			
		||||
@@ -6,13 +7,18 @@ const setup = require("./setup.js");
 | 
			
		||||
test("app runs", async (t) => {
 | 
			
		||||
  t.timeoutAfter(10e3);
 | 
			
		||||
  setup.resetTestDataDir();
 | 
			
		||||
  const app = setup.createApp();
 | 
			
		||||
  const app = await setup.createApp();
 | 
			
		||||
  try {
 | 
			
		||||
    await setup.waitForLoad(app, t);
 | 
			
		||||
    await app.client.windowByIndex(1); // Focus on webview
 | 
			
		||||
    await (await app.client.$('//*[@id="connect"]')).waitForExist(); // Id of the connect button
 | 
			
		||||
    await setup.endTest(app, t);
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    await setup.endTest(app, t, error || "error");
 | 
			
		||||
    const windows = chan();
 | 
			
		||||
    for (const win of app.windows()) put(windows, win);
 | 
			
		||||
    app.on("window", (win) => put(windows, win));
 | 
			
		||||
 | 
			
		||||
    const mainWindow = await take(windows);
 | 
			
		||||
    t.equal(await mainWindow.title(), "Zulip");
 | 
			
		||||
 | 
			
		||||
    const mainWebview = await take(windows);
 | 
			
		||||
    await mainWebview.waitForSelector("#connect");
 | 
			
		||||
  } finally {
 | 
			
		||||
    await setup.endTest(app);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,66 +1,28 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
const path = require("path");
 | 
			
		||||
 | 
			
		||||
const {_electron} = require("playwright-core");
 | 
			
		||||
const rimraf = require("rimraf");
 | 
			
		||||
const {Application} = require("spectron");
 | 
			
		||||
 | 
			
		||||
const testsPkg = require("./package.json");
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  createApp,
 | 
			
		||||
  endTest,
 | 
			
		||||
  waitForLoad,
 | 
			
		||||
  wait,
 | 
			
		||||
  resetTestDataDir,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Runs Zulip Desktop.
 | 
			
		||||
// Returns a promise that resolves to a Spectron Application once the app has loaded.
 | 
			
		||||
// Takes a Tape test. Makes some basic assertions to verify that the app loaded correctly.
 | 
			
		||||
// Returns a promise that resolves to an Electron Application once the app has loaded.
 | 
			
		||||
function createApp() {
 | 
			
		||||
  return new Application({
 | 
			
		||||
    path: path.join(
 | 
			
		||||
      __dirname,
 | 
			
		||||
      "..",
 | 
			
		||||
      "node_modules",
 | 
			
		||||
      ".bin",
 | 
			
		||||
      "electron" + (process.platform === "win32" ? ".cmd" : ""),
 | 
			
		||||
    ),
 | 
			
		||||
  return _electron.launch({
 | 
			
		||||
    args: [path.join(__dirname)], // Ensure this dir has a package.json file with a 'main' entry piont
 | 
			
		||||
    env: {NODE_ENV: "test"},
 | 
			
		||||
    waitTimeout: 10e3,
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Starts the app, waits for it to load, returns a promise
 | 
			
		||||
async function waitForLoad(app, t, options) {
 | 
			
		||||
  if (!options) {
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  await app.start();
 | 
			
		||||
  await app.client.waitUntilWindowLoaded();
 | 
			
		||||
  await app.client.pause(2000);
 | 
			
		||||
  const title = await app.webContents.getTitle();
 | 
			
		||||
  t.equal(title, "Zulip", "html title");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns a promise that resolves after 'ms' milliseconds. Default: 1 second
 | 
			
		||||
async function wait(ms) {
 | 
			
		||||
  if (ms === undefined) {
 | 
			
		||||
    ms = 1000;
 | 
			
		||||
  } // Default: wait long enough for the UI to update
 | 
			
		||||
 | 
			
		||||
  return new Promise((resolve) => {
 | 
			
		||||
    setTimeout(resolve, ms);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Quit the app, end the test, either in success (!err) or failure (err)
 | 
			
		||||
async function endTest(app, t, error) {
 | 
			
		||||
  await app.client.windowByIndex(0);
 | 
			
		||||
  await app.stop();
 | 
			
		||||
  t.end(error);
 | 
			
		||||
// Quit the app, end the test
 | 
			
		||||
async function endTest(app) {
 | 
			
		||||
  await app.close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getAppDataDir() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
const {chan, put, take} = require("medium");
 | 
			
		||||
const test = require("tape");
 | 
			
		||||
 | 
			
		||||
const setup = require("./setup.js");
 | 
			
		||||
@@ -6,20 +7,22 @@ const setup = require("./setup.js");
 | 
			
		||||
test("add-organization", async (t) => {
 | 
			
		||||
  t.timeoutAfter(50e3);
 | 
			
		||||
  setup.resetTestDataDir();
 | 
			
		||||
  const app = setup.createApp();
 | 
			
		||||
  const app = await setup.createApp();
 | 
			
		||||
  try {
 | 
			
		||||
    await setup.waitForLoad(app, t);
 | 
			
		||||
    await app.client.windowByIndex(1); // Focus on webview
 | 
			
		||||
    await (
 | 
			
		||||
      await app.client.$(".setting-input-value")
 | 
			
		||||
    ).setValue("chat.zulip.org");
 | 
			
		||||
    await (await app.client.$("#connect")).click();
 | 
			
		||||
    await setup.wait(5000);
 | 
			
		||||
    await app.client.windowByIndex(0); // Switch focus back to main win
 | 
			
		||||
    await app.client.windowByIndex(1); // Switch focus back to org webview
 | 
			
		||||
    await (await app.client.$('//*[@id="id_username"]')).waitForExist();
 | 
			
		||||
    await setup.endTest(app, t);
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    await setup.endTest(app, t, error || "error");
 | 
			
		||||
    const windows = chan();
 | 
			
		||||
    for (const win of app.windows()) put(windows, win);
 | 
			
		||||
    app.on("window", (win) => put(windows, win));
 | 
			
		||||
 | 
			
		||||
    const mainWindow = await take(windows);
 | 
			
		||||
    t.equal(await mainWindow.title(), "Zulip");
 | 
			
		||||
 | 
			
		||||
    const mainWebview = await take(windows);
 | 
			
		||||
    await mainWebview.fill(".setting-input-value", "chat.zulip.org");
 | 
			
		||||
    await mainWebview.click("#connect");
 | 
			
		||||
 | 
			
		||||
    const orgWebview = await take(windows);
 | 
			
		||||
    await orgWebview.waitForSelector("#id_username");
 | 
			
		||||
  } finally {
 | 
			
		||||
    await setup.endTest(app);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
const {chan, put, take} = require("medium");
 | 
			
		||||
const test = require("tape");
 | 
			
		||||
 | 
			
		||||
const setup = require("./setup.js");
 | 
			
		||||
@@ -8,14 +9,18 @@ const setup = require("./setup.js");
 | 
			
		||||
test("new-org-link", async (t) => {
 | 
			
		||||
  t.timeoutAfter(50e3);
 | 
			
		||||
  setup.resetTestDataDir();
 | 
			
		||||
  const app = setup.createApp();
 | 
			
		||||
  const app = await setup.createApp();
 | 
			
		||||
  try {
 | 
			
		||||
    await setup.waitForLoad(app, t);
 | 
			
		||||
    await app.client.windowByIndex(1); // Focus on webview
 | 
			
		||||
    await (await app.client.$("#open-create-org-link")).click(); // Click on new org link button
 | 
			
		||||
    await setup.wait(5000);
 | 
			
		||||
    await setup.endTest(app, t);
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    await setup.endTest(app, t, error || "error");
 | 
			
		||||
    const windows = chan();
 | 
			
		||||
    for (const win of app.windows()) put(windows, win);
 | 
			
		||||
    app.on("window", (win) => put(windows, win));
 | 
			
		||||
 | 
			
		||||
    const mainWindow = await take(windows);
 | 
			
		||||
    t.equal(await mainWindow.title(), "Zulip");
 | 
			
		||||
 | 
			
		||||
    const mainWebview = await take(windows);
 | 
			
		||||
    await mainWebview.click("#open-create-org-link");
 | 
			
		||||
  } finally {
 | 
			
		||||
    await setup.endTest(app);
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user