mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-03-25 14:53:06 -04:00
Replaced dropdowns in the navbar with JS-less ones from https://codeberg.org/forgejo/forgejo/pulls/7906. Also made some changes to the dropdown component: * fixed variable name * painted backgrounds (hover, focus) are now consistently applied to the actual interactive items (`<a>`, `<button>`), not to `<li>`. This is consistent with how backgrounds are conditionally applied to pre-selected (`.active`) items and is better, as it allows to place additional things to `<li>`... * ...`<hr>` can now be placed in some `<li>` instead of requiring splitting into multiple `<ul>`. This is simpler in code and I am guessing this should be better for a11y as screen readers can cast one continuous list instead of multiple ones. But have no hard proof that this is actually better. My main motivation was to avoid ugly mistake-prone tmpl logic where unconditional `<ul>` was getting closed and reopened inside of a condition. I should note that on mobile all items, including these dropdowns, are hidden in another dropdown, and it stays JS-dependand for now. So this PR only makes this part of the UI JS-less for desktop. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10025 Reviewed-by: Robert Wolff <mahlzahn@posteo.de> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: 0ko <0ko@noreply.codeberg.org> Co-committed-by: 0ko <0ko@noreply.codeberg.org>
70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// @watch start
|
|
// templates/user/auth/**
|
|
// templates/user/settings/**
|
|
// web_src/js/features/user-**
|
|
// @watch end
|
|
|
|
import {expect} from '@playwright/test';
|
|
import {test, create_temp_user, login_user} from './utils_e2e.ts';
|
|
import {screenshot} from './shared/screenshots.ts';
|
|
|
|
test('WebAuthn register & login flow', async ({browser, request}, workerInfo) => {
|
|
test.skip(workerInfo.project.name !== 'chromium', 'Uses Chrome protocol');
|
|
const {context, username} = await create_temp_user(browser, workerInfo, request);
|
|
const page = await context.newPage();
|
|
|
|
// Register a security key.
|
|
let response = await page.goto('/user/settings/security');
|
|
expect(response?.status()).toBe(200);
|
|
|
|
// https://github.com/microsoft/playwright/issues/7276#issuecomment-1516768428
|
|
const cdpSession = await page.context().newCDPSession(page);
|
|
await cdpSession.send('WebAuthn.enable');
|
|
await cdpSession.send('WebAuthn.addVirtualAuthenticator', {
|
|
options: {
|
|
protocol: 'ctap2',
|
|
ctap2Version: 'ctap2_1',
|
|
hasUserVerification: true,
|
|
transport: 'usb',
|
|
automaticPresenceSimulation: true,
|
|
isUserVerified: true,
|
|
},
|
|
});
|
|
|
|
await page.locator('input#nickname').fill('Testing Security Key');
|
|
await screenshot(page, page.locator('.user-setting-content'));
|
|
await page.getByText('Add security key').click();
|
|
await expect(page.getByRole('button', {name: 'Remove'})).toBeVisible(); // "Remove" button is visible, indicating that the security key was added
|
|
|
|
// Logout.
|
|
await page.locator('summary[aria-label="Profile and settings…"]').click();
|
|
await page.getByText('Sign out').click();
|
|
await expect(async () => {
|
|
await page.waitForURL(`${workerInfo.project.use.baseURL}/`);
|
|
}).toPass();
|
|
|
|
// Login.
|
|
response = await page.goto('/user/login');
|
|
expect(response?.status()).toBe(200);
|
|
|
|
await page.getByLabel('Username or email address').fill(username);
|
|
await page.getByLabel('Password').fill('password');
|
|
await page.getByRole('button', {name: 'Sign in'}).click();
|
|
await page.waitForURL(`${workerInfo.project.use.baseURL}/user/webauthn`);
|
|
await page.waitForURL(`${workerInfo.project.use.baseURL}/`);
|
|
|
|
// Cleanup.
|
|
response = await page.goto('/user/settings/security');
|
|
expect(response?.status()).toBe(200);
|
|
await page.getByRole('button', {name: 'Remove'}).click();
|
|
await screenshot(page, page.locator('.ui.g-modal-confirm.delete.modal'), 50);
|
|
await page.getByRole('button', {name: 'Yes'}).click();
|
|
await expect(page.getByRole('button', {name: 'Remove'})).toBeHidden();
|
|
await page.waitForLoadState();
|
|
|
|
// verify the user can login without a key
|
|
await login_user(browser, workerInfo, username);
|
|
});
|