mirror of
https://github.com/nextcloud/all-in-one.git
synced 2025-12-21 06:56:57 +00:00
test: add e2e tests via playwright
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
This commit is contained in:
parent
4f68d3ed1c
commit
e37611a759
7 changed files with 392 additions and 0 deletions
95
php/tests/tests/initial-setup.spec.js
Normal file
95
php/tests/tests/initial-setup.spec.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { writeFileSync } from 'node:fs'
|
||||
|
||||
test('Initial setup', async ({ page: setupPage }) => {
|
||||
test.setTimeout(10 * 60 * 1000)
|
||||
|
||||
// Extract initial password
|
||||
await setupPage.goto('./setup');
|
||||
const password = await setupPage.locator('#initial-password').innerText()
|
||||
const containersPagePromise = setupPage.waitForEvent('popup');
|
||||
await setupPage.getByRole('link', { name: 'Open Nextcloud AIO login ↗' }).click();
|
||||
const containersPage = await containersPagePromise;
|
||||
|
||||
// Log in and wait for redirect
|
||||
await containersPage.locator('#master-password').click();
|
||||
await containersPage.locator('#master-password').fill(password);
|
||||
await containersPage.getByRole('button', { name: 'Log in' }).click();
|
||||
await containersPage.waitForURL('./containers');
|
||||
|
||||
// Reject IP addresses
|
||||
await containersPage.locator('#domain').click();
|
||||
await containersPage.locator('#domain').fill('1.1.1.1');
|
||||
await containersPage.getByRole('button', { name: 'Submit domain' }).click();
|
||||
await expect(containersPage.locator('body')).toContainText('Please enter a domain and not an IP-address!');
|
||||
|
||||
// Accept example.com (requires disabled domain validation)
|
||||
await containersPage.locator('#domain').click();
|
||||
await containersPage.locator('#domain').fill('example.com');
|
||||
await containersPage.getByRole('button', { name: 'Submit domain' }).click();
|
||||
|
||||
// Disable all additional containers
|
||||
await containersPage.locator('#talk').uncheck();
|
||||
await containersPage.getByRole('checkbox', { name: 'Whiteboard' }).uncheck();
|
||||
await containersPage.getByRole('checkbox', { name: 'Imaginary' }).uncheck();
|
||||
await containersPage.getByRole('checkbox', { name: 'Collabora' }).uncheck();
|
||||
await containersPage.getByRole('button', { name: 'Save changes' }).click();
|
||||
await expect(containersPage.locator('#talk')).not.toBeChecked()
|
||||
await expect(containersPage.getByRole('checkbox', { name: 'Whiteboard' })).not.toBeChecked()
|
||||
await expect(containersPage.getByRole('checkbox', { name: 'Imaginary' })).not.toBeChecked()
|
||||
await expect(containersPage.getByRole('checkbox', { name: 'Collabora' })).not.toBeChecked()
|
||||
|
||||
// Reject invalid time zones
|
||||
await containersPage.locator('#timezone').click();
|
||||
await containersPage.locator('#timezone').fill('Invalid time zone');
|
||||
containersPage.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`)
|
||||
dialog.accept()
|
||||
});
|
||||
await containersPage.getByRole('button', { name: 'Submit timezone' }).click();
|
||||
await expect(containersPage.locator('body')).toContainText('The entered timezone does not seem to be a valid timezone!')
|
||||
|
||||
// Accept valid time zone
|
||||
await containersPage.locator('#timezone').click();
|
||||
await containersPage.locator('#timezone').fill('Europe/Berlin');
|
||||
containersPage.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`)
|
||||
dialog.accept()
|
||||
});
|
||||
await containersPage.getByRole('button', { name: 'Submit timezone' }).click();
|
||||
|
||||
// Start containers and wait for starting message
|
||||
await containersPage.getByRole('button', { name: 'Download and start containers' }).click();
|
||||
await expect(containersPage.getByRole('link', { name: 'Open your Nextcloud ↗' })).toBeVisible({ timeout: 5 * 60 * 1000 });
|
||||
await expect(containersPage.getByRole('link', { name: 'Open your Nextcloud ↗' })).toHaveAttribute('href', 'https://example.com');
|
||||
|
||||
// Extract initial nextcloud password
|
||||
await expect(containersPage.getByRole('main')).toContainText('Initial Nextcloud password:')
|
||||
const initialNextcloudPassword = await containersPage.locator('#initial-nextcloud-password').innerText();
|
||||
|
||||
// Set backup location and create backup
|
||||
const borgBackupLocation = `/mnt/test/aio-${Math.floor(Math.random() * 2147483647)}`
|
||||
await containersPage.locator('#borg_backup_host_location').click();
|
||||
await containersPage.locator('#borg_backup_host_location').fill(borgBackupLocation);
|
||||
await containersPage.getByRole('button', { name: 'Submit backup location' }).click();
|
||||
containersPage.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`)
|
||||
dialog.accept()
|
||||
});
|
||||
await containersPage.getByRole('button', { name: 'Create backup' }).click();
|
||||
await expect(containersPage.getByRole('main')).toContainText('Backup container is currently running:', { timeout: 3 * 60 * 1000 });
|
||||
await expect(containersPage.getByRole('main')).toContainText('Last backup successful on', { timeout: 3 * 60 * 1000 });
|
||||
await containersPage.getByText('Click here to reveal all backup options').click();
|
||||
await expect(containersPage.locator('#borg-backup-password')).toBeVisible();
|
||||
const borgBackupPassword = await containersPage.locator('#borg-backup-password').innerText();
|
||||
|
||||
// Assert that all containers are stopped
|
||||
await expect(containersPage.getByRole('button', { name: 'Start containers' })).toBeVisible();
|
||||
|
||||
// Save passwords for restore backup test
|
||||
writeFileSync('test_data.json', JSON.stringify({
|
||||
initialNextcloudPassword,
|
||||
borgBackupLocation,
|
||||
borgBackupPassword,
|
||||
}))
|
||||
});
|
||||
79
php/tests/tests/restore-instance.spec.js
Normal file
79
php/tests/tests/restore-instance.spec.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
test('Restore instance', async ({ page: setupPage }) => {
|
||||
test.setTimeout(10 * 60 * 1000)
|
||||
|
||||
// Load passwords from previous test
|
||||
const {
|
||||
initialNextcloudPassword,
|
||||
borgBackupLocation,
|
||||
borgBackupPassword,
|
||||
} = JSON.parse(readFileSync('test_data.json'))
|
||||
|
||||
// Extract initial password
|
||||
await setupPage.goto('./setup');
|
||||
const password = await setupPage.locator('#initial-password').innerText()
|
||||
const containersPagePromise = setupPage.waitForEvent('popup');
|
||||
await setupPage.getByRole('link', { name: 'Open Nextcloud AIO login ↗' }).click();
|
||||
const containersPage = await containersPagePromise;
|
||||
|
||||
// Log in and wait for redirect
|
||||
await containersPage.locator('#master-password').click();
|
||||
await containersPage.locator('#master-password').fill(password);
|
||||
await containersPage.getByRole('button', { name: 'Log in' }).click();
|
||||
await containersPage.waitForURL('./containers');
|
||||
|
||||
// Reject example.com (requires enabled domain validation)
|
||||
await containersPage.locator('#domain').click();
|
||||
await containersPage.locator('#domain').fill('example.com');
|
||||
await containersPage.getByRole('button', { name: 'Submit domain' }).click();
|
||||
await expect(containersPage.locator('body')).toContainText('Domain does not point to this server or the reverse proxy is not configured correctly.');
|
||||
|
||||
// Reject invalid backup location
|
||||
await containersPage.locator('#borg_restore_host_location').click();
|
||||
await containersPage.locator('#borg_restore_host_location').fill('/mnt/foobar');
|
||||
await containersPage.locator('#borg_restore_password').click();
|
||||
await containersPage.locator('#borg_restore_password').fill('foobar');
|
||||
await containersPage.getByRole('button', { name: 'Submit location and encryption password' }).click()
|
||||
await containersPage.getByRole('button', { name: 'Test path and encryption' }).click();
|
||||
await expect(containersPage.getByRole('main')).toContainText('Last test failed!', { timeout: 60 * 1000 });
|
||||
|
||||
// Reject invalid backup password
|
||||
await containersPage.locator('#borg_restore_host_location').click();
|
||||
await containersPage.locator('#borg_restore_host_location').fill('/mnt/backup');
|
||||
await containersPage.locator('#borg_restore_password').click();
|
||||
await containersPage.locator('#borg_restore_password').fill('foobar');
|
||||
await containersPage.getByRole('button', { name: 'Submit location and encryption password' }).click()
|
||||
await containersPage.getByRole('button', { name: 'Test path and encryption' }).click();
|
||||
await expect(containersPage.getByRole('main')).toContainText('Last test failed!', { timeout: 60 * 1000 });
|
||||
|
||||
// Accept correct backup location and password
|
||||
await containersPage.locator('#borg_restore_host_location').click();
|
||||
await containersPage.locator('#borg_restore_host_location').fill(borgBackupLocation);
|
||||
await containersPage.locator('#borg_restore_password').click();
|
||||
await containersPage.locator('#borg_restore_password').fill(borgBackupPassword);
|
||||
await containersPage.getByRole('button', { name: 'Submit location and encryption password' }).click()
|
||||
await containersPage.getByRole('button', { name: 'Test path and encryption' }).click();
|
||||
|
||||
// Check integrity and restore backup
|
||||
await containersPage.getByRole('button', { name: 'Check backup integrity' }).click();
|
||||
await expect(containersPage.getByRole('main')).toContainText('Last check successful!', { timeout: 5 * 60 * 1000 });
|
||||
await containersPage.getByRole('button', { name: 'Restore selected backup' }).click();
|
||||
await expect(containersPage.getByRole('main')).toContainText('Backup container is currently running:');
|
||||
|
||||
// Verify a successful backup restore
|
||||
await expect(containersPage.getByRole('main')).toContainText('Last restore successful!', { timeout: 3 * 60 * 1000 });
|
||||
await expect(containersPage.getByRole('main')).toContainText('⚠️ Container updates are available. Click on Stop containers and Start and update containers to update them. You should consider creating a backup first.');
|
||||
containersPage.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`)
|
||||
dialog.accept()
|
||||
});
|
||||
await containersPage.getByRole('button', { name: 'Start and update containers' }).click();
|
||||
await expect(containersPage.getByRole('link', { name: 'Open your Nextcloud ↗' })).toBeVisible({ timeout: 5 * 60 * 1000 });
|
||||
await expect(containersPage.getByRole('main')).toContainText(initialNextcloudPassword);
|
||||
|
||||
// Verify that containers are all stopped
|
||||
await containersPage.getByRole('button', { name: 'Stop containers' }).click();
|
||||
await expect(containersPage.getByRole('button', { name: 'Start containers' })).toBeVisible({ timeout: 60 * 1000 });
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue