Files
notesnook/apps/desktop/__tests__/auto-updates.test.ts

243 lines
6.3 KiB
TypeScript
Raw Permalink Normal View History

/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { testCleanup, test } from "./test-override.js";
import { writeFile } from "fs/promises";
import { Page } from "playwright";
import { gt, lt } from "semver";
2025-07-19 11:01:57 +05:00
import { describe } from "vitest";
2025-07-19 11:01:57 +05:00
test("update starts downloading if version is outdated", async ({
ctx: { page },
expect,
onTestFinished
}) => {
onTestFinished(testCleanup);
2025-07-19 11:01:57 +05:00
await page.waitForSelector("#authForm");
expect(
await page.getByRole("button", { name: "Create account" }).isVisible()
).toBe(true);
2025-07-19 11:01:57 +05:00
await page
.getByRole("button", { name: "Skip & go directly to the app" })
.click();
2025-07-19 11:01:57 +05:00
await skipDialog(page);
2025-07-19 11:01:57 +05:00
await page.waitForSelector(".ProseMirror");
2025-07-19 11:01:57 +05:00
await page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /updating/i })
.waitFor({ state: "attached" });
});
2025-07-19 11:01:57 +05:00
test("update is only shown if version is outdated and auto updates are disabled", async ({
ctx,
expect,
onTestFinished
}) => {
onTestFinished(testCleanup);
await ctx.app.close();
await writeFile(
ctx.configPath,
JSON.stringify({
automaticUpdates: false
})
);
2025-07-19 11:01:57 +05:00
await ctx.relaunch();
2025-07-19 11:01:57 +05:00
const { page } = ctx;
2025-07-19 11:01:57 +05:00
await page.waitForSelector("#authForm");
2025-07-19 11:01:57 +05:00
expect(
await page.getByRole("button", { name: "Create account" }).isVisible()
).toBe(true);
2025-07-19 11:01:57 +05:00
await page
.getByRole("button", { name: "Skip & go directly to the app" })
.click();
2025-07-19 11:01:57 +05:00
await skipDialog(page);
2025-07-19 11:01:57 +05:00
await page.waitForSelector(".ProseMirror");
2025-07-19 11:01:57 +05:00
await page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /available/i })
.waitFor({ state: "attached" });
});
2025-07-19 11:01:57 +05:00
describe("update to stable if it is newer", () => {
test.scoped({ options: { version: "3.0.0-beta.0" } });
test("test", async ({ ctx, expect, onTestFinished }) => {
onTestFinished(testCleanup);
await ctx.app.close();
await writeFile(
ctx.configPath,
JSON.stringify({
automaticUpdates: false,
releaseTrack: "beta"
})
);
2025-07-19 11:01:57 +05:00
await ctx.relaunch();
2025-07-19 11:01:57 +05:00
const { page } = ctx;
2025-07-19 11:01:57 +05:00
await page.waitForSelector("#authForm");
2025-07-19 11:01:57 +05:00
expect(
await page.getByRole("button", { name: "Create account" }).isVisible()
).toBe(true);
2025-07-19 11:01:57 +05:00
await page
.getByRole("button", { name: "Skip & go directly to the app" })
.click();
2025-07-19 11:01:57 +05:00
await skipDialog(page);
2025-07-19 11:01:57 +05:00
await page.waitForSelector(".ProseMirror");
2025-07-19 11:01:57 +05:00
const updateButton = page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /available/i });
await updateButton.waitFor({ state: "visible" });
const content = await updateButton.textContent();
const version = content?.split(" ")?.[0] || "";
expect(gt(version, "3.0.0-beta.0")).toBe(true);
});
});
2025-07-19 11:01:57 +05:00
describe("update is not available if it latest stable version is older", () => {
test.scoped({ options: { version: "99.0.0-beta.0" } });
test("test", async ({ ctx, expect, onTestFinished }) => {
onTestFinished(testCleanup);
await ctx.app.close();
await writeFile(
ctx.configPath,
JSON.stringify({
automaticUpdates: false,
releaseTrack: "beta"
})
);
2025-07-19 11:01:57 +05:00
await ctx.relaunch();
2025-07-19 11:01:57 +05:00
const { page } = ctx;
2025-07-19 11:01:57 +05:00
await page.waitForSelector("#authForm");
2025-07-19 11:01:57 +05:00
expect(
await page.getByRole("button", { name: "Create account" }).isVisible()
).toBe(true);
2025-07-19 11:01:57 +05:00
await page
.getByRole("button", { name: "Skip & go directly to the app" })
.click();
2025-07-19 11:01:57 +05:00
await skipDialog(page);
2025-07-19 11:01:57 +05:00
await page.waitForSelector(".ProseMirror");
2025-07-19 11:01:57 +05:00
await page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /checking for updates/i })
.waitFor({ state: "hidden" });
expect(
await page
.locator(".theme-scope-statusBar")
2025-07-19 11:01:57 +05:00
.getByRole("button", { name: /available/i })
.isHidden()
).toBe(true);
});
});
2025-07-19 11:01:57 +05:00
describe("downgrade to stable on switching to stable release track", () => {
test.scoped({ options: { version: "99.0.0-beta.0" } });
test("test", async ({ ctx, expect, onTestFinished }) => {
onTestFinished(testCleanup);
await ctx.app.close();
await writeFile(
ctx.configPath,
JSON.stringify({
automaticUpdates: false,
releaseTrack: "stable"
})
);
2025-07-19 11:01:57 +05:00
await ctx.relaunch();
2025-07-19 11:01:57 +05:00
const { page } = ctx;
2025-07-19 11:01:57 +05:00
await page.waitForSelector("#authForm");
2025-07-19 11:01:57 +05:00
expect(
await page.getByRole("button", { name: "Create account" }).isVisible()
).toBe(true);
2025-07-19 11:01:57 +05:00
await page
.getByRole("button", { name: "Skip & go directly to the app" })
.click();
2025-07-19 11:01:57 +05:00
await skipDialog(page);
2025-07-19 11:01:57 +05:00
await page.waitForSelector(".ProseMirror");
2025-07-19 11:01:57 +05:00
await page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /checking for updates/i })
.waitFor({ state: "hidden" });
2025-07-19 11:01:57 +05:00
const updateButton = page
.locator(".theme-scope-statusBar")
.getByRole("button", { name: /available/i });
await updateButton.waitFor({ state: "visible" });
const content = await updateButton.textContent();
const version = content?.split(" ")?.[0] || "";
expect(lt(version, "99.0.0-beta.0")).toBe(true);
});
});
async function skipDialog(page: Page) {
2025-07-19 09:43:39 +05:00
try {
const dialog = page.locator(".ReactModal__Content");
const positiveButton = dialog.locator(
"button[data-role='positive-button']"
);
const negativeButton = dialog.locator(
"button[data-role='negative-button']"
);
if (await positiveButton.isVisible())
2025-07-19 11:01:57 +05:00
await positiveButton.click({ timeout: 1000 });
2025-07-19 09:43:39 +05:00
else if (await negativeButton.isVisible())
2025-07-19 11:01:57 +05:00
await negativeButton.click({ timeout: 1000 });
2025-07-19 09:43:39 +05:00
} catch (e) {
// ignore error
}
}