Browse Source
# Conflicts: # src/components/notifications/SMTP.vue # src/languages/en.jspull/451/head
LouisLam
3 years ago
51 changed files with 8235 additions and 1187 deletions
@ -0,0 +1,34 @@ |
|||||
|
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node |
||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions |
||||
|
|
||||
|
name: Auto Test |
||||
|
|
||||
|
on: |
||||
|
push: |
||||
|
branches: [ master ] |
||||
|
pull_request: |
||||
|
branches: [ master ] |
||||
|
|
||||
|
jobs: |
||||
|
build: |
||||
|
runs-on: ubuntu-latest |
||||
|
|
||||
|
strategy: |
||||
|
matrix: |
||||
|
node-version: [14.x, 15.x, 16.x] |
||||
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ |
||||
|
|
||||
|
steps: |
||||
|
- uses: actions/checkout@v2 |
||||
|
|
||||
|
- name: Use Node.js ${{ matrix.node-version }} |
||||
|
uses: actions/setup-node@v2 |
||||
|
with: |
||||
|
node-version: ${{ matrix.node-version }} |
||||
|
cache: 'npm' |
||||
|
- run: npm ci |
||||
|
- run: npm run build |
||||
|
- run: npm test |
||||
|
env: |
||||
|
HEADLESS_TEST: 1 |
||||
|
JUST_FOR_TEST: ${{ secrets.JUST_FOR_TEST }} |
@ -0,0 +1,6 @@ |
|||||
|
module.exports = { |
||||
|
"launch": { |
||||
|
"headless": process.env.HEADLESS_TEST || false, |
||||
|
"userDataDir": "./data/test-chrome-profile", |
||||
|
} |
||||
|
}; |
File diff suppressed because it is too large
@ -0,0 +1,52 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<h4>{{ $t("Certificate Info") }}</h4> |
||||
|
{{ $t("Certificate Chain") }}: |
||||
|
<div |
||||
|
v-if="valid" |
||||
|
class="rounded d-inline-flex ms-2 text-white tag-valid" |
||||
|
> |
||||
|
{{ $t("Valid") }} |
||||
|
</div> |
||||
|
<div |
||||
|
v-if="!valid" |
||||
|
class="rounded d-inline-flex ms-2 text-white tag-invalid" |
||||
|
> |
||||
|
{{ $t("Invalid") }} |
||||
|
</div> |
||||
|
<certificate-info-row :cert="certInfo" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import CertificateInfoRow from "./CertificateInfoRow.vue"; |
||||
|
export default { |
||||
|
components: { |
||||
|
CertificateInfoRow, |
||||
|
}, |
||||
|
props: { |
||||
|
certInfo: { |
||||
|
type: Object, |
||||
|
required: true, |
||||
|
}, |
||||
|
valid: { |
||||
|
type: Boolean, |
||||
|
required: true, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import "../assets/vars.scss"; |
||||
|
|
||||
|
.tag-valid { |
||||
|
padding: 2px 25px; |
||||
|
background-color: $primary; |
||||
|
} |
||||
|
|
||||
|
.tag-invalid { |
||||
|
padding: 2px 25px; |
||||
|
background-color: $danger; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,122 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="d-flex flex-row align-items-center p-1 overflow-hidden"> |
||||
|
<div class="m-3 ps-3"> |
||||
|
<div class="cert-icon"> |
||||
|
<font-awesome-icon icon="file" /> |
||||
|
<font-awesome-icon class="award-icon" icon="award" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="m-3"> |
||||
|
<table class="text-start"> |
||||
|
<tbody> |
||||
|
<tr class="my-3"> |
||||
|
<td class="px-3">Subject:</td> |
||||
|
<td>{{ formatSubject(cert.subject) }}</td> |
||||
|
</tr> |
||||
|
<tr class="my-3"> |
||||
|
<td class="px-3">Valid To:</td> |
||||
|
<td><Datetime :value="cert.validTo" /></td> |
||||
|
</tr> |
||||
|
<tr class="my-3"> |
||||
|
<td class="px-3">Days Remaining:</td> |
||||
|
<td>{{ cert.daysRemaining }}</td> |
||||
|
</tr> |
||||
|
<tr class="my-3"> |
||||
|
<td class="px-3">Issuer:</td> |
||||
|
<td>{{ formatSubject(cert.issuer) }}</td> |
||||
|
</tr> |
||||
|
<tr class="my-3"> |
||||
|
<td class="px-3">Fingerprint:</td> |
||||
|
<td>{{ cert.fingerprint }}</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="d-flex"> |
||||
|
<font-awesome-icon |
||||
|
v-if="cert.issuerCertificate" |
||||
|
class="m-2 ps-6 link-icon" |
||||
|
icon="link" |
||||
|
/> |
||||
|
</div> |
||||
|
<certificate-info-row |
||||
|
v-if="cert.issuerCertificate" |
||||
|
:cert="cert.issuerCertificate" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import Datetime from "../components/Datetime.vue"; |
||||
|
export default { |
||||
|
name: "CertificateInfoRow", |
||||
|
components: { |
||||
|
Datetime, |
||||
|
}, |
||||
|
props: { |
||||
|
cert: { |
||||
|
type: Object, |
||||
|
required: true, |
||||
|
}, |
||||
|
}, |
||||
|
methods: { |
||||
|
formatSubject(subject) { |
||||
|
if (subject.O && subject.CN && subject.C) { |
||||
|
return `${subject.CN} - ${subject.O} (${subject.C})`; |
||||
|
} else if (subject.O && subject.CN) { |
||||
|
return `${subject.CN} - ${subject.O}`; |
||||
|
} else if (subject.CN) { |
||||
|
return subject.CN; |
||||
|
} else { |
||||
|
return "no info"; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
@import "../assets/vars.scss"; |
||||
|
|
||||
|
table { |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.cert-icon { |
||||
|
position: relative; |
||||
|
font-size: 70px; |
||||
|
color: $link-color; |
||||
|
opacity: 0.5; |
||||
|
|
||||
|
.dark & { |
||||
|
color: $dark-font-color; |
||||
|
opacity: 0.3; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.award-icon { |
||||
|
position: absolute; |
||||
|
font-size: 0.5em; |
||||
|
bottom: 20%; |
||||
|
left: 12%; |
||||
|
color: white; |
||||
|
|
||||
|
.dark & { |
||||
|
color: $dark-bg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.link-icon { |
||||
|
font-size: 20px; |
||||
|
margin-left: 50px !important; |
||||
|
color: $link-color; |
||||
|
opacity: 0.5; |
||||
|
|
||||
|
.dark & { |
||||
|
color: $dark-font-color; |
||||
|
opacity: 0.3; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,199 @@ |
|||||
|
export default { |
||||
|
languageName: "Magyar", |
||||
|
checkEverySecond: "Ellenőrzés {0} másodpercenként", |
||||
|
retryCheckEverySecond: "Újrapróbál {0} másodpercenként.", |
||||
|
retriesDescription: "Maximális próbálkozás mielőtt a szolgáltatás leállt jelőlést kap és értesítés kerül kiküldésre", |
||||
|
ignoreTLSError: "TLS/SSL hibák figyelnen kívül hagyása HTTPS weboldalaknál", |
||||
|
upsideDownModeDescription: "Az állapot megfordítása. Ha a szolgáltatás elérhető, akkor lesz leállt állapotú.", |
||||
|
maxRedirectDescription: "Az átirányítások maximális száma. állítsa 0-ra az átirányítás tiltásához.", |
||||
|
acceptedStatusCodesDescription: "Válassza ki az állapot kódokat amelyek sikeres válasznak fognak számítani.", |
||||
|
passwordNotMatchMsg: "A megismételt jelszó nem egyezik.", |
||||
|
notificationDescription: "Kérem, rendeljen egy értesítést a figyeléshez, hogy működjön.", |
||||
|
keywordDescription: "Kulcsszó keresése a html-ben vagy a JSON válaszban. (kis-nagybetű érzékeny)", |
||||
|
pauseDashboardHome: "Szünetel", |
||||
|
deleteMonitorMsg: "Biztos, hogy törölni akarja ezt a figyelőt?", |
||||
|
deleteNotificationMsg: "Biztos, hogy törölni akarja ezt az értesítést az összes figyelőnél?", |
||||
|
resoverserverDescription: "A Cloudflare az alapértelmezett szerver, bármikor meg tudja változtatni a resolver server-t.", |
||||
|
rrtypeDescription: "Válassza ki az RR-Típust a figyelőhöz", |
||||
|
pauseMonitorMsg: "Biztos, hogy szüneteltetni akarja?", |
||||
|
enableDefaultNotificationDescription: "Minden új figyelőhöz ez az értesítés engedélyezett lesz alapértelmezetten. Kikapcsolhatja az értesítést külön minden figyelőnél.", |
||||
|
clearEventsMsg: "Biztos, hogy törölni akar miden eseményt ennél a figyelnél?", |
||||
|
clearHeartbeatsMsg: "Biztos, hogy törölni akar minden heartbeat-et ennél a figyelőnél?", |
||||
|
confirmClearStatisticsMsg: "Biztos, hogy törölni akat MINDEN statisztikát?", |
||||
|
importHandleDescription: "Válassza a 'Meglévő kihagyását', ha ki szeretné hagyni az azonos nevő figyelőket vagy értesítésket. A 'Felülírás' törölni fog minden meglévő figyelőt és értesítést.", |
||||
|
confirmImportMsg: "Biztos, hogy importálja a mentést? Győzödjön meg róla, hogy jól választotta ki az importálás opciót.", |
||||
|
twoFAVerifyLabel: "Kérem, adja meg a token-t, hogy a 2FA működését ellenőrizzük", |
||||
|
tokenValidSettingsMsg: "A token érvényes! El tudja menteni a 2FA beállításait.", |
||||
|
confirmEnableTwoFAMsg: "Biztosan engedélyezi a 2FA-t?", |
||||
|
confirmDisableTwoFAMsg: "Biztosan letiltja a 2FA-t?", |
||||
|
Settings: "Beállítások", |
||||
|
Dashboard: "Irányítópult", |
||||
|
"New Update": "Új frissítés", |
||||
|
Language: "Nyelv", |
||||
|
Appearance: "Megjelenés", |
||||
|
Theme: "Téma", |
||||
|
General: "Általános", |
||||
|
Version: "Verzió", |
||||
|
"Check Update On GitHub": "Frissítések keresése a GitHub-on", |
||||
|
List: "Lista", |
||||
|
Add: "Hozzáadás", |
||||
|
"Add New Monitor": "Új figyelő hozzáadása", |
||||
|
"Quick Stats": "Gyors statisztikák", |
||||
|
Up: "Működik", |
||||
|
Down: "Leállt", |
||||
|
Pending: "Függőben", |
||||
|
Unknown: "Ismeretlen", |
||||
|
Pause: "Szünet", |
||||
|
Name: "Név", |
||||
|
Status: "Állapot", |
||||
|
DateTime: "Időpont", |
||||
|
Message: "Üzenet", |
||||
|
"No important events": "Nincs fontos esemény", |
||||
|
Resume: "Folytatás", |
||||
|
Edit: "Szerkesztés", |
||||
|
Delete: "Törlés", |
||||
|
Current: "Aktuális", |
||||
|
Uptime: "Uptime", |
||||
|
"Cert Exp.": "Tanúsítvány lejár", |
||||
|
days: "napok", |
||||
|
day: "nap", |
||||
|
"-day": "-nap", |
||||
|
hour: "óra", |
||||
|
"-hour": "-óra", |
||||
|
Response: "Válasz", |
||||
|
Ping: "Ping", |
||||
|
"Monitor Type": "Figyelő típusa", |
||||
|
Keyword: "Kulcsszó", |
||||
|
"Friendly Name": "Rövid név", |
||||
|
URL: "URL", |
||||
|
Hostname: "Hostnév", |
||||
|
Port: "Port", |
||||
|
"Heartbeat Interval": "Heartbeat időköz", |
||||
|
Retries: "Újrapróbálkozás", |
||||
|
"Heartbeat Retry Interval": "Heartbeat újrapróbálkozások időköze", |
||||
|
Advanced: "Haladó", |
||||
|
"Upside Down Mode": "Fordított mód", |
||||
|
"Max. Redirects": "Max. átirányítás", |
||||
|
"Accepted Status Codes": "Elfogadott állapot kódok", |
||||
|
Save: "Mentés", |
||||
|
Notifications: "Értesítések", |
||||
|
"Not available, please setup.": "Nem elérhető, állítsa be.", |
||||
|
"Setup Notification": "Értesítés beállítása", |
||||
|
Light: "Világos", |
||||
|
Dark: "Sötét", |
||||
|
Auto: "Auto", |
||||
|
"Theme - Heartbeat Bar": "Téma - Heartbeat Bar", |
||||
|
Normal: "Normal", |
||||
|
Bottom: "Nyomógomb", |
||||
|
None: "Nincs", |
||||
|
Timezone: "Időzóna", |
||||
|
"Search Engine Visibility": "Látható a keresőmotoroknak", |
||||
|
"Allow indexing": "Indexelés engedélyezése", |
||||
|
"Discourage search engines from indexing site": "Keresőmotorok elriasztása az oldal indexelésétől", |
||||
|
"Change Password": "Jelszó változtatása", |
||||
|
"Current Password": "Jelenlegi jelszó", |
||||
|
"New Password": "Új jelszó", |
||||
|
"Repeat New Password": "Ismételje meg az új jelszót", |
||||
|
"Update Password": "Jelszó módosítása", |
||||
|
"Disable Auth": "Hitelesítés tiltása", |
||||
|
"Enable Auth": "Hitelesítés engedélyezése", |
||||
|
Logout: "Kijelenetkezés", |
||||
|
Leave: "Elhagy", |
||||
|
"I understand, please disable": "Megértettem, kérem tilsa le", |
||||
|
Confirm: "Megerősítés", |
||||
|
Yes: "Igen", |
||||
|
No: "Nem", |
||||
|
Username: "Felhasználónév", |
||||
|
Password: "Jelszó", |
||||
|
"Remember me": "Emlékezzen rám", |
||||
|
Login: "Bejelentkezés", |
||||
|
"No Monitors, please": "Nincs figyelő, kérem", |
||||
|
"add one": "adjon hozzá egyet", |
||||
|
"Notification Type": "Értesítés típusa", |
||||
|
Email: "Email", |
||||
|
Test: "Teszt", |
||||
|
"Certificate Info": "Tanúsítvány információk", |
||||
|
"Resolver Server": "Resolver szerver", |
||||
|
"Resource Record Type": "Resource Record típusa", |
||||
|
"Last Result": "Utolsó eredmény", |
||||
|
"Create your admin account": "Hozza létre az adminisztrátor felhasználót", |
||||
|
"Repeat Password": "Jelszó ismétlése", |
||||
|
"Import Backup": "Mentés importálása", |
||||
|
"Export Backup": "Mentés exportálása", |
||||
|
Export: "Exportálás", |
||||
|
Import: "Importálás", |
||||
|
respTime: "Válaszidő (ms)", |
||||
|
notAvailableShort: "N/A", |
||||
|
"Default enabled": "Alapértelmezetten engedélyezett", |
||||
|
"Apply on all existing monitors": "Alkalmazza az összes figyelőre", |
||||
|
Create: "Létrehozás", |
||||
|
"Clear Data": "Adatok törlése", |
||||
|
Events: "Események", |
||||
|
Heartbeats: "Heartbeats", |
||||
|
"Auto Get": "Auto Get", |
||||
|
backupDescription: "Ki tudja menteni az összes figyelőt és értesítést egy JSON fájlba.", |
||||
|
backupDescription2: "Ui.: Történeti és esemény adatokat nem tartalmaz.", |
||||
|
backupDescription3: "Érzékeny adatok, pl. szolgáltatás kulcsok is vannak az export fájlban. Figyelmesen őrizze!", |
||||
|
alertNoFile: "Válaszzon ki egy fájlt az importáláshoz.", |
||||
|
alertWrongFileType: "Válasszon egy JSON fájlt.", |
||||
|
"Clear all statistics": "Összes statisztika törlése", |
||||
|
"Skip existing": "Meglévő kihagyása", |
||||
|
Overwrite: "Felülírás", |
||||
|
Options: "Opciók", |
||||
|
"Keep both": "Mindegyiket tartsa meg", |
||||
|
"Verify Token": "Token ellenőrzése", |
||||
|
"Setup 2FA": "2FA beállítása", |
||||
|
"Enable 2FA": "2FA engedélyezése", |
||||
|
"Disable 2FA": "2FA toltása", |
||||
|
"2FA Settings": "2FA beállítások", |
||||
|
"Two Factor Authentication": "Two Factor Authentication", |
||||
|
Active: "Aktív", |
||||
|
Inactive: "Inaktív", |
||||
|
Token: "Token", |
||||
|
"Show URI": "URI megmutatása", |
||||
|
Tags: "Cimkék", |
||||
|
"Add New below or Select...": "Adjon hozzá lentre vagy válasszon...", |
||||
|
"Tag with this name already exist.": "Ilyen nevű cimke már létezik.", |
||||
|
"Tag with this value already exist.": "Ilyen értékű cimke már létezik.", |
||||
|
color: "szín", |
||||
|
"value (optional)": "érték (opcionális)", |
||||
|
Gray: "Szürke", |
||||
|
Red: "Piros", |
||||
|
Orange: "Narancs", |
||||
|
Green: "Zöld", |
||||
|
Blue: "Kék", |
||||
|
Indigo: "Indigó", |
||||
|
Purple: "Lila", |
||||
|
Pink: "Rózsaszín", |
||||
|
"Search...": "Keres...", |
||||
|
"Avg. Ping": "Átl. ping", |
||||
|
"Avg. Response": "Átl. válasz", |
||||
|
"Entry Page": "Nyitólap", |
||||
|
statusPageNothing: "Semmi nincs itt, kérem, adjon hozzá egy figyelőt.", |
||||
|
"No Services": "Nincs szolgáltatás", |
||||
|
"All Systems Operational": "Minden rendszer működik", |
||||
|
"Partially Degraded Service": "Részlegesen leállt szolgáltatás", |
||||
|
"Degraded Service": "Leállt szolgáltatás", |
||||
|
"Add Group": "Csoport hozzáadása", |
||||
|
"Add a monitor": "Figyelő hozzáadása", |
||||
|
"Edit Status Page": "Sátusz oldal szerkesztése", |
||||
|
"Go to Dashboard": "Menj az irányítópulthoz", |
||||
|
telegram: "Telegram", |
||||
|
webhook: "Webhook", |
||||
|
smtp: "Email (SMTP)", |
||||
|
discord: "Discord", |
||||
|
teams: "Microsoft Teams", |
||||
|
signal: "Signal", |
||||
|
gotify: "Gotify", |
||||
|
slack: "Slack", |
||||
|
"rocket.chat": "Rocket.chat", |
||||
|
pushover: "Pushover", |
||||
|
pushy: "Pushy", |
||||
|
octopush: "Octopush", |
||||
|
lunasea: "LunaSea", |
||||
|
apprise: "Apprise (Support 50+ Notification services)", |
||||
|
pushbullet: "Pushbullet", |
||||
|
line: "Line Messenger", |
||||
|
mattermost: "Mattermost", |
||||
|
"Status Page": "Status Page", |
||||
|
}; |
@ -0,0 +1,9 @@ |
|||||
|
const fs = require("fs"); |
||||
|
|
||||
|
const path = "./data/test-chrome-profile"; |
||||
|
|
||||
|
if (fs.existsSync(path)) { |
||||
|
fs.rmdirSync(path, { |
||||
|
recursive: true, |
||||
|
}); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
const fs = require("fs"); |
||||
|
|
||||
|
const path = "./data/test"; |
||||
|
|
||||
|
if (fs.existsSync(path)) { |
||||
|
fs.rmdirSync(path, { |
||||
|
recursive: true, |
||||
|
}); |
||||
|
} |
@ -0,0 +1,236 @@ |
|||||
|
// eslint-disable-next-line no-unused-vars
|
||||
|
const { Page, Browser } = require("puppeteer"); |
||||
|
const { sleep } = require("../src/util"); |
||||
|
const axios = require("axios"); |
||||
|
|
||||
|
/** |
||||
|
* Set back the correct data type for page object |
||||
|
* @type {Page} |
||||
|
*/ |
||||
|
page; |
||||
|
|
||||
|
/** |
||||
|
* @type {Browser} |
||||
|
*/ |
||||
|
browser; |
||||
|
|
||||
|
beforeAll(async () => { |
||||
|
await page.setViewport({ |
||||
|
width: 1280, |
||||
|
height: 720, |
||||
|
deviceScaleFactor: 1, |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
afterAll(() => { |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
const baseURL = "http://127.0.0.1:3002"; |
||||
|
|
||||
|
describe("Init", () => { |
||||
|
const title = "Uptime Kuma"; |
||||
|
|
||||
|
beforeAll(async () => { |
||||
|
await page.goto(baseURL); |
||||
|
}); |
||||
|
|
||||
|
it(`should be titled "${title}"`, async () => { |
||||
|
await expect(page.title()).resolves.toMatch(title); |
||||
|
}); |
||||
|
|
||||
|
// Setup Page
|
||||
|
it("Setup", async () => { |
||||
|
// Create an Admin
|
||||
|
await page.waitForSelector("#floatingInput"); |
||||
|
await page.waitForSelector("#repeat"); |
||||
|
await page.click("#floatingInput"); |
||||
|
await page.type("#floatingInput", "admin"); |
||||
|
await page.type("#floatingPassword", "admin123"); |
||||
|
await page.type("#repeat", "admin123"); |
||||
|
await page.click(".btn-primary[type=submit]"); |
||||
|
await sleep(3000); |
||||
|
|
||||
|
// Go to /setup again
|
||||
|
await page.goto(baseURL + "/setup"); |
||||
|
await sleep(3000); |
||||
|
let pathname = await page.evaluate(() => location.pathname); |
||||
|
expect(pathname).toEqual("/dashboard"); |
||||
|
|
||||
|
// Go to /
|
||||
|
await page.goto(baseURL); |
||||
|
await sleep(3000); |
||||
|
pathname = await page.evaluate(() => location.pathname); |
||||
|
expect(pathname).toEqual("/dashboard"); |
||||
|
}); |
||||
|
|
||||
|
// Settings Page
|
||||
|
describe("Settings", () => { |
||||
|
beforeAll(async () => { |
||||
|
await page.goto(baseURL + "/settings"); |
||||
|
}); |
||||
|
|
||||
|
it("Change Language", async () => { |
||||
|
await page.waitForSelector("#language"); |
||||
|
|
||||
|
await page.select("#language", "zh-HK"); |
||||
|
let languageTitle = await page.evaluate(() => document.querySelector("[for=language]").innerText); |
||||
|
expect(languageTitle).toMatch("語言"); |
||||
|
|
||||
|
await page.select("#language", "en"); |
||||
|
languageTitle = await page.evaluate(() => document.querySelector("[for=language]").innerText); |
||||
|
expect(languageTitle).toMatch("Language"); |
||||
|
}); |
||||
|
|
||||
|
it("Change Theme", async () => { |
||||
|
await sleep(1000); |
||||
|
|
||||
|
// Dark
|
||||
|
await click(page, ".btn[for=btncheck2]"); |
||||
|
await page.waitForSelector("div.dark"); |
||||
|
|
||||
|
await sleep(1000); |
||||
|
|
||||
|
// Light
|
||||
|
await click(page, ".btn[for=btncheck1]"); |
||||
|
await page.waitForSelector("div.light"); |
||||
|
}); |
||||
|
|
||||
|
// TODO: Heartbeat Bar Style
|
||||
|
|
||||
|
// TODO: Timezone
|
||||
|
|
||||
|
it("Search Engine Visibility", async () => { |
||||
|
// Default
|
||||
|
let res = await axios.get(baseURL + "/robots.txt"); |
||||
|
expect(res.data).toMatch("Disallow: /"); |
||||
|
|
||||
|
// Yes
|
||||
|
await click(page, "#searchEngineIndexYes"); |
||||
|
await click(page, "form > div > .btn[type=submit]"); |
||||
|
await sleep(2000); |
||||
|
res = await axios.get(baseURL + "/robots.txt"); |
||||
|
expect(res.data).not.toMatch("Disallow: /"); |
||||
|
|
||||
|
// No
|
||||
|
await click(page, "#searchEngineIndexNo"); |
||||
|
await click(page, "form > div > .btn[type=submit]"); |
||||
|
await sleep(2000); |
||||
|
res = await axios.get(baseURL + "/robots.txt"); |
||||
|
expect(res.data).toMatch("Disallow: /"); |
||||
|
}); |
||||
|
|
||||
|
it("Entry Page", async () => { |
||||
|
const newPage = await browser.newPage(); |
||||
|
|
||||
|
// Default
|
||||
|
await newPage.goto(baseURL); |
||||
|
await sleep(3000); |
||||
|
let pathname = await newPage.evaluate(() => location.pathname); |
||||
|
expect(pathname).toEqual("/dashboard"); |
||||
|
|
||||
|
// Status Page
|
||||
|
await click(page, "#entryPageNo"); |
||||
|
await click(page, "form > div > .btn[type=submit]"); |
||||
|
await sleep(2000); |
||||
|
await newPage.goto(baseURL); |
||||
|
await sleep(3000); |
||||
|
pathname = await newPage.evaluate(() => location.pathname); |
||||
|
expect(pathname).toEqual("/status"); |
||||
|
|
||||
|
// Back to Dashboard
|
||||
|
await click(page, "#entryPageYes"); |
||||
|
await click(page, "form > div > .btn[type=submit]"); |
||||
|
await sleep(2000); |
||||
|
await newPage.goto(baseURL); |
||||
|
await sleep(3000); |
||||
|
pathname = await newPage.evaluate(() => location.pathname); |
||||
|
expect(pathname).toEqual("/dashboard"); |
||||
|
|
||||
|
await newPage.close(); |
||||
|
}); |
||||
|
|
||||
|
it("Change Password (wrong current password)", async () => { |
||||
|
await page.type("#current-password", "wrong_passw$$d"); |
||||
|
await page.type("#new-password", "new_password123"); |
||||
|
await page.type("#repeat-new-password", "new_password123"); |
||||
|
await click(page, "form > div > .btn[type=submit]", 1); |
||||
|
await sleep(3000); |
||||
|
await click(page, ".btn-danger.btn.me-1"); |
||||
|
await sleep(2000); |
||||
|
await login("admin", "new_password123"); |
||||
|
await sleep(2000); |
||||
|
let elementCount = await page.evaluate(() => document.querySelectorAll("#floatingPassword").length); |
||||
|
expect(elementCount).toEqual(1); |
||||
|
|
||||
|
await login("admin", "admin123"); |
||||
|
await sleep(3000); |
||||
|
}); |
||||
|
|
||||
|
it("Change Password (wrong repeat)", async () => { |
||||
|
await page.type("#current-password", "admin123"); |
||||
|
await page.type("#new-password", "new_password123"); |
||||
|
await page.type("#repeat-new-password", "new_password1234567898797898"); |
||||
|
await click(page, "form > div > .btn[type=submit]", 1); |
||||
|
await sleep(3000); |
||||
|
await click(page, ".btn-danger.btn.me-1"); |
||||
|
await sleep(2000); |
||||
|
await login("admin", "new_password123"); |
||||
|
await sleep(2000); |
||||
|
let elementCount = await page.evaluate(() => document.querySelectorAll("#floatingPassword").length); |
||||
|
expect(elementCount).toEqual(1); |
||||
|
|
||||
|
await login("admin", "admin123"); |
||||
|
await sleep(3000); |
||||
|
}); |
||||
|
|
||||
|
// TODO: 2FA
|
||||
|
|
||||
|
// TODO: Export Backup
|
||||
|
|
||||
|
// TODO: Import Backup
|
||||
|
|
||||
|
// TODO: Disable Auth
|
||||
|
|
||||
|
// TODO: Clear Stats
|
||||
|
}); |
||||
|
|
||||
|
/* |
||||
|
* TODO |
||||
|
* Create Monitor - All type |
||||
|
* Edit Monitor |
||||
|
* Delete Monitor |
||||
|
* |
||||
|
* Create Notification (token problem, maybe hard to test) |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
describe("Status Page", () => { |
||||
|
const title = "Uptime Kuma"; |
||||
|
beforeAll(async () => { |
||||
|
await page.goto(baseURL + "/status"); |
||||
|
}); |
||||
|
it(`should be titled "${title}"`, async () => { |
||||
|
await expect(page.title()).resolves.toMatch(title); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
async function login(username, password) { |
||||
|
await input(page, "#floatingInput", username); |
||||
|
await input(page, "#floatingPassword", password); |
||||
|
await page.click(".btn-primary[type=submit]"); |
||||
|
} |
||||
|
|
||||
|
async function click(page, selector, elementIndex = 0) { |
||||
|
return await page.evaluate((s, i) => { |
||||
|
return document.querySelectorAll(s)[i].click(); |
||||
|
}, selector, elementIndex); |
||||
|
} |
||||
|
|
||||
|
async function input(page, selector, text) { |
||||
|
const element = await page.$(selector); |
||||
|
await element.click({ clickCount: 3 }); |
||||
|
await page.keyboard.press("Backspace"); |
||||
|
await page.type(selector, text); |
||||
|
} |
Loading…
Reference in new issue