From 00717755254b441c6bfb7cecab15e5a741507499 Mon Sep 17 00:00:00 2001 From: Easy Date: Tue, 1 Oct 2024 16:28:47 +0800 Subject: [PATCH 01/11] Add serverchan3 support for serverchan notification provider (#5145) Co-authored-by: Frank Elsinga --- server/notification-providers/serverchan.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/notification-providers/serverchan.js b/server/notification-providers/serverchan.js index cefe61f14..ab9308c3e 100644 --- a/server/notification-providers/serverchan.js +++ b/server/notification-providers/serverchan.js @@ -11,8 +11,13 @@ class ServerChan extends NotificationProvider { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { const okMsg = "Sent Successfully."; + // serverchan3 requires sending via ft07.com + const url = String(notification.serverChanSendKey).startsWith("sctp") + ? `https://${notification.serverChanSendKey}.push.ft07.com/send` + : `https://sctapi.ftqq.com/${notification.serverChanSendKey}.send`; + try { - await axios.post(`https://sctapi.ftqq.com/${notification.serverChanSendKey}.send`, { + await axios.post(url, { "title": this.checkStatus(heartbeatJSON, monitorJSON), "desp": msg, }); From a309cf0e2cdfa0a9f9a39215c163b90e52eece9c Mon Sep 17 00:00:00 2001 From: artshllaku <77685827+artshllk@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:20:27 +0200 Subject: [PATCH 02/11] tests: improve playwright test readability (#5149) --- test/e2e/specs/monitor-form.spec.js | 67 +++++++++++++--------------- test/e2e/specs/setup-process.once.js | 17 ++++--- test/e2e/specs/status-page.spec.js | 2 +- 3 files changed, 40 insertions(+), 46 deletions(-) diff --git a/test/e2e/specs/monitor-form.spec.js b/test/e2e/specs/monitor-form.spec.js index 7efc117c0..7a84f3c93 100644 --- a/test/e2e/specs/monitor-form.spec.js +++ b/test/e2e/specs/monitor-form.spec.js @@ -1,8 +1,22 @@ import { expect, test } from "@playwright/test"; import { login, restoreSqliteSnapshot, screenshot } from "../util-test"; -test.describe("Monitor Form", () => { +/** + * Selects the monitor type from the dropdown. + * @param {import('@playwright/test').Page} page - The Playwright page instance. + * @param {string} monitorType - The monitor type to select (default is "dns"). + * @returns {Promise} - A promise that resolves when the monitor type is selected. + */ +async function selectMonitorType(page, monitorType = "dns") { + const monitorTypeSelect = page.getByTestId("monitor-type-select"); + await expect(monitorTypeSelect).toBeVisible(); + await monitorTypeSelect.selectOption(monitorType); + const selectedValue = await monitorTypeSelect.evaluate((select) => select.value); + expect(selectedValue).toBe(monitorType); +} + +test.describe("Monitor Form", () => { test.beforeEach(async ({ page }) => { await restoreSqliteSnapshot(page); }); @@ -11,30 +25,20 @@ test.describe("Monitor Form", () => { await page.goto("./add"); await login(page); await screenshot(testInfo, page); + await selectMonitorType(page); - const monitorTypeSelect = page.getByTestId("monitor-type-select"); - await expect(monitorTypeSelect).toBeVisible(); - - await monitorTypeSelect.selectOption("dns"); - const selectedValue = await monitorTypeSelect.evaluate(select => select.value); - expect(selectedValue).toBe("dns"); - - // Add Conditions & verify: await page.getByTestId("add-condition-button").click(); expect(await page.getByTestId("condition").count()).toEqual(2); // 1 added by default + 1 explicitly added - // Add a Condition Group & verify: await page.getByTestId("add-group-button").click(); expect(await page.getByTestId("condition-group").count()).toEqual(1); expect(await page.getByTestId("condition").count()).toEqual(3); // 2 solo conditions + 1 condition in group await screenshot(testInfo, page); - // Remove a condition & verify: await page.getByTestId("remove-condition").first().click(); expect(await page.getByTestId("condition").count()).toEqual(2); // 1 solo condition + 1 condition in group - // Remove a condition group & verify: await page.getByTestId("remove-condition-group").first().click(); expect(await page.getByTestId("condition-group").count()).toEqual(0); @@ -45,33 +49,29 @@ test.describe("Monitor Form", () => { await page.goto("./add"); await login(page); await screenshot(testInfo, page); - - const monitorTypeSelect = page.getByTestId("monitor-type-select"); - await expect(monitorTypeSelect).toBeVisible(); - - await monitorTypeSelect.selectOption("dns"); - const selectedValue = await monitorTypeSelect.evaluate(select => select.value); - expect(selectedValue).toBe("dns"); + await selectMonitorType(page); const friendlyName = "Example DNS NS"; await page.getByTestId("friendly-name-input").fill(friendlyName); await page.getByTestId("hostname-input").fill("example.com"); - // Vue-Multiselect component const resolveTypeSelect = page.getByTestId("resolve-type-select"); await resolveTypeSelect.click(); await resolveTypeSelect.getByRole("option", { name: "NS" }).click(); await page.getByTestId("add-condition-button").click(); expect(await page.getByTestId("condition").count()).toEqual(2); // 1 added by default + 1 explicitly added + await page.getByTestId("condition-value").nth(0).fill("a.iana-servers.net"); await page.getByTestId("condition-and-or").nth(0).selectOption("or"); await page.getByTestId("condition-value").nth(1).fill("b.iana-servers.net"); - await screenshot(testInfo, page); + await screenshot(testInfo, page); await page.getByTestId("save-button").click(); - await page.waitForURL("/dashboard/*"); // wait for the monitor to be created - await expect(page.getByTestId("monitor-status")).toHaveText("up", { ignoreCase: true }); + await page.waitForURL("/dashboard/*"); + + expect(page.getByTestId("monitor-status")).toHaveText("up", { ignoreCase: true }); + await screenshot(testInfo, page); }); @@ -79,31 +79,26 @@ test.describe("Monitor Form", () => { await page.goto("./add"); await login(page); await screenshot(testInfo, page); - - const monitorTypeSelect = page.getByTestId("monitor-type-select"); - await expect(monitorTypeSelect).toBeVisible(); - - await monitorTypeSelect.selectOption("dns"); - const selectedValue = await monitorTypeSelect.evaluate(select => select.value); - expect(selectedValue).toBe("dns"); + await selectMonitorType(page); const friendlyName = "Example DNS NS"; await page.getByTestId("friendly-name-input").fill(friendlyName); await page.getByTestId("hostname-input").fill("example.com"); - // Vue-Multiselect component const resolveTypeSelect = page.getByTestId("resolve-type-select"); await resolveTypeSelect.click(); await resolveTypeSelect.getByRole("option", { name: "NS" }).click(); expect(await page.getByTestId("condition").count()).toEqual(1); // 1 added by default - await page.getByTestId("condition-value").nth(0).fill("definitely-not.net"); - await screenshot(testInfo, page); + await page.getByTestId("condition-value").nth(0).fill("definitely-not.net"); + + await screenshot(testInfo, page); await page.getByTestId("save-button").click(); - await page.waitForURL("/dashboard/*"); // wait for the monitor to be created - await expect(page.getByTestId("monitor-status")).toHaveText("down", { ignoreCase: true }); + await page.waitForURL("/dashboard/*"); + + expect(page.getByTestId("monitor-status")).toHaveText("down", { ignoreCase: true }); + await screenshot(testInfo, page); }); - }); diff --git a/test/e2e/specs/setup-process.once.js b/test/e2e/specs/setup-process.once.js index 0dde0cdc4..f1bdf2b48 100644 --- a/test/e2e/specs/setup-process.once.js +++ b/test/e2e/specs/setup-process.once.js @@ -5,6 +5,10 @@ test.describe("Uptime Kuma Setup", () => { test.skip(() => getSqliteDatabaseExists(), "Must only run once per session"); + test.afterEach(async ({ page }, testInfo) => { + await screenshot(testInfo, page); + }); + /* * Setup */ @@ -15,10 +19,9 @@ test.describe("Uptime Kuma Setup", () => { await page.getByRole("button", { name: "Next" }).click(); await screenshot(testInfo, page); await page.waitForURL("/setup"); // ensures the server is ready to continue to the next test - await screenshot(testInfo, page); }); - test("setup admin", async ({ page }, testInfo) => { + test("setup admin", async ({ page }) => { await page.goto("./"); await page.getByPlaceholder("Username").click(); await page.getByPlaceholder("Username").fill("admin"); @@ -27,30 +30,26 @@ test.describe("Uptime Kuma Setup", () => { await page.getByPlaceholder("Password", { exact: true }).press("Tab"); await page.getByPlaceholder("Repeat Password").fill("admin123"); await page.getByRole("button", { name: "Create" }).click(); - await screenshot(testInfo, page); }); /* * All other tests should be run after setup */ - test("login", async ({ page }, testInfo) => { + test("login", async ({ page }) => { await page.goto("./dashboard"); await login(page); - await screenshot(testInfo, page); }); - test("logout", async ({ page }, testInfo) => { + test("logout", async ({ page }) => { await page.goto("./dashboard"); await login(page); await page.getByText("A", { exact: true }).click(); await page.getByRole("button", { name: "Log out" }).click(); - await screenshot(testInfo, page); }); - test("take sqlite snapshot", async ({ page }, testInfo) => { + test("take sqlite snapshot", async ({ page }) => { await takeSqliteSnapshot(page); - await screenshot(testInfo, page); }); }); diff --git a/test/e2e/specs/status-page.spec.js b/test/e2e/specs/status-page.spec.js index 48398b1cf..f525dfc6f 100644 --- a/test/e2e/specs/status-page.spec.js +++ b/test/e2e/specs/status-page.spec.js @@ -95,7 +95,7 @@ test.describe("Status Page", () => { await expect(page.getByTestId("powered-by")).toHaveCount(0); await expect(page.getByTestId("update-countdown-text")).toContainText("00:"); - const updateCountdown = Number((await page.getByTestId("update-countdown-text").textContent()).match(/(\d+):(\d+)/)[2]) ; + const updateCountdown = Number((await page.getByTestId("update-countdown-text").textContent()).match(/(\d+):(\d+)/)[2]); expect(updateCountdown).toBeGreaterThanOrEqual(refreshInterval); // cant be certain when the timer will start, so ensure it's within expected range expect(updateCountdown).toBeLessThanOrEqual(refreshInterval + 10); From e40ce59e6603df275e21fa24b7f6cd7d77574d03 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Fri, 4 Oct 2024 02:54:28 +0200 Subject: [PATCH 03/11] Better description for shrink database button (#4814) Co-authored-by: Adam Stachowicz --- src/components/settings/MonitorHistory.vue | 9 ++++++++- src/lang/ar-SY.json | 1 - src/lang/ar.json | 1 - src/lang/bg-BG.json | 1 - src/lang/cs-CZ.json | 1 - src/lang/da-DK.json | 1 - src/lang/de-CH.json | 1 - src/lang/de-DE.json | 1 - src/lang/el-GR.json | 1 - src/lang/en.json | 2 +- src/lang/es-ES.json | 1 - src/lang/eu.json | 1 - src/lang/fa.json | 1 - src/lang/fi.json | 1 - src/lang/fr-FR.json | 1 - src/lang/ga.json | 1 - src/lang/he-IL.json | 1 - src/lang/hr-HR.json | 1 - src/lang/hu.json | 1 - src/lang/id-ID.json | 1 - src/lang/it-IT.json | 1 - src/lang/ja.json | 1 - src/lang/ko-KR.json | 1 - src/lang/nl-NL.json | 1 - src/lang/pl.json | 1 - src/lang/pt-BR.json | 1 - src/lang/pt-PT.json | 1 - src/lang/ro.json | 1 - src/lang/ru-RU.json | 1 - src/lang/sl-SI.json | 1 - src/lang/sv-SE.json | 1 - src/lang/te.json | 1 - src/lang/th-TH.json | 1 - src/lang/tr-TR.json | 1 - src/lang/uk-UA.json | 1 - src/lang/ur.json | 1 - src/lang/vi-VN.json | 1 - src/lang/zh-CN.json | 1 - src/lang/zh-HK.json | 1 - src/lang/zh-TW.json | 1 - 40 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/components/settings/MonitorHistory.vue b/src/components/settings/MonitorHistory.vue index befedf513..25e3e1559 100644 --- a/src/components/settings/MonitorHistory.vue +++ b/src/components/settings/MonitorHistory.vue @@ -32,7 +32,14 @@ -
{{ $t("shrinkDatabaseDescription") }}
+ + + + + @@ -1000,9 +1010,58 @@ +