mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
fix tests, add autofocus disable option for dropdown
This commit is contained in:
@@ -109,7 +109,7 @@ services:
|
||||
- sail
|
||||
- reverse-proxy
|
||||
playwright:
|
||||
image: mcr.microsoft.com/playwright:v1.50.0-jammy
|
||||
image: mcr.microsoft.com/playwright:v1.51.1-jammy
|
||||
command: ['npx', 'playwright', 'test', '--ui-port=8080', '--ui-host=0.0.0.0']
|
||||
working_dir: /src
|
||||
extra_hosts:
|
||||
|
||||
@@ -36,7 +36,7 @@ test('can register and delete account', async ({ page }) => {
|
||||
await page.goto(PLAYWRIGHT_BASE_URL + '/user/profile');
|
||||
await page.getByRole('button', { name: 'Delete Account' }).click();
|
||||
await page.getByPlaceholder('Password').fill(password);
|
||||
await page.getByRole('button', { name: 'Delete Account' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Delete Account' }).click();
|
||||
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
|
||||
await page.goto(PLAYWRIGHT_BASE_URL + '/login');
|
||||
await page.getByLabel('Email').fill(email);
|
||||
|
||||
@@ -16,7 +16,7 @@ test('test that creating and deleting a new client via the modal works', async (
|
||||
await page.getByRole('button', { name: 'Create Client' }).click();
|
||||
await page.getByPlaceholder('Client Name').fill(newClientName);
|
||||
await Promise.all([
|
||||
page.getByRole('button', { name: 'Create Client' }).nth(1).click(),
|
||||
page.getByRole('button', { name: 'Create Client' }).click(),
|
||||
page.waitForResponse(
|
||||
async (response) =>
|
||||
response.url().includes('/clients') &&
|
||||
@@ -56,12 +56,12 @@ test('test that archiving and unarchiving clients works', async ({ page }) => {
|
||||
await page.getByRole('button', { name: 'Create Client' }).click();
|
||||
await page.getByLabel('Client Name').fill(newClientName);
|
||||
|
||||
await page.getByRole('button', { name: 'Create Client' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Client' }).click();
|
||||
await expect(page.getByText(newClientName)).toBeVisible();
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Archive').first().click(),
|
||||
page.getByRole('menuitem').getByText('Archive').click(),
|
||||
expect(page.getByText(newClientName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
@@ -71,7 +71,7 @@ test('test that archiving and unarchiving clients works', async ({ page }) => {
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Unarchive').first().click(),
|
||||
page.getByRole('menuitem').getByText('Unarchive').click(),
|
||||
expect(page.getByText(newClientName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
|
||||
@@ -82,7 +82,7 @@ test('test that organization billable rate can be updated with all existing time
|
||||
await goToMembersPage(page);
|
||||
const newBillableRate = Math.round(Math.random() * 10000);
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await page.getByRole('button').getByText('Edit').first().click();
|
||||
await page.getByRole('menuitem').getByText('Edit').click();
|
||||
await page.getByText('Organization Default Rate').click();
|
||||
await page.getByText('Custom Rate').click();
|
||||
await page
|
||||
|
||||
@@ -17,7 +17,7 @@ test('test that updating project member billable rate works for existing time en
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
|
||||
await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await expect(page.getByText(newProjectName)).toBeVisible();
|
||||
|
||||
await page.getByText(newProjectName).click();
|
||||
@@ -35,8 +35,7 @@ test('test that updating project member billable rate works for existing time en
|
||||
.getByRole('button')
|
||||
.click();
|
||||
await page
|
||||
.getByRole('button', { name: 'Edit Project Member' })
|
||||
.first()
|
||||
.getByRole('menuitem', { name: 'Edit Project Member' })
|
||||
.click();
|
||||
await page.getByLabel('Billable Rate').fill(newBillableRate.toString());
|
||||
await page.getByRole('button', { name: 'Update Project Member' }).click();
|
||||
|
||||
@@ -17,7 +17,7 @@ test('test that creating and deleting a new project via the modal works', async
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
await Promise.all([
|
||||
page.getByRole('button', { name: 'Create Project' }).nth(1).click(),
|
||||
page.getByRole('button', { name: 'Create Project' }).click(),
|
||||
page.waitForResponse(
|
||||
async (response) =>
|
||||
response.url().includes('/projects') &&
|
||||
@@ -62,12 +62,12 @@ test('test that archiving and unarchiving projects works', async ({ page }) => {
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
|
||||
await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await expect(page.getByText(newProjectName)).toBeVisible();
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Archive').first().click(),
|
||||
page.getByRole('menuitem').getByText('Archive').first().click(),
|
||||
expect(page.getByText(newProjectName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
@@ -77,7 +77,7 @@ test('test that archiving and unarchiving projects works', async ({ page }) => {
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Unarchive').first().click(),
|
||||
page.getByRole('menuitem').getByText('Unarchive').first().click(),
|
||||
expect(page.getByText(newProjectName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
@@ -96,11 +96,11 @@ test('test that updating billable rate works with existing time entries', async
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
|
||||
await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await expect(page.getByText(newProjectName)).toBeVisible();
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await page.getByRole('button').getByText('Edit').first().click(),
|
||||
await page.getByRole('menuitem').getByText('Edit').first().click();
|
||||
await page.getByText('Non-Billable').click();
|
||||
await page.getByText('Custom Rate').click();
|
||||
await page
|
||||
|
||||
@@ -15,7 +15,7 @@ test('test that creating and deleting a new client via the modal works', async (
|
||||
await page.getByRole('button', { name: 'Create Tag' }).click();
|
||||
await page.getByPlaceholder('Tag Name').fill(newTagName);
|
||||
await Promise.all([
|
||||
page.getByRole('button', { name: 'Create Tag' }).nth(1).click(),
|
||||
page.getByRole('button', { name: 'Create Tag' }).click(),
|
||||
page.waitForResponse(
|
||||
async (response) =>
|
||||
response.url().includes('/tags') &&
|
||||
|
||||
@@ -16,7 +16,7 @@ test('test that creating and deleting a new tag in a new project works', async (
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
await Promise.all([
|
||||
page.getByRole('button', { name: 'Create Project' }).nth(1).click(),
|
||||
page.getByRole('button', { name: 'Create Project' }).click(),
|
||||
page.waitForResponse(
|
||||
async (response) =>
|
||||
response.url().includes('/projects') &&
|
||||
@@ -41,7 +41,7 @@ test('test that creating and deleting a new tag in a new project works', async (
|
||||
await page.getByPlaceholder('Task Name').fill(newTaskName);
|
||||
|
||||
await Promise.all([
|
||||
page.getByRole('button', { name: 'Create Task' }).nth(1).click(),
|
||||
page.getByRole('button', { name: 'Create Task' }).click(),
|
||||
page.waitForResponse(
|
||||
async (response) =>
|
||||
response.url().includes('/tasks') &&
|
||||
@@ -107,20 +107,20 @@ test('test that archiving and unarchiving tasks works', async ({ page }) => {
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await page.getByLabel('Project Name').fill(newProjectName);
|
||||
|
||||
await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Project' }).click();
|
||||
await expect(page.getByText(newProjectName)).toBeVisible();
|
||||
|
||||
await page.getByText(newProjectName).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Create Task' }).click();
|
||||
await page.getByPlaceholder('Task Name').fill(newTaskName);
|
||||
await page.getByRole('button', { name: 'Create Task' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create Task' }).click();
|
||||
|
||||
await expect(page.getByRole('table')).toContainText(newTaskName);
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Mark as done').first().click(),
|
||||
page.getByRole('menuitem').getByText('Mark as done').first().click(),
|
||||
expect(page.getByText(newTaskName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
@@ -130,7 +130,7 @@ test('test that archiving and unarchiving tasks works', async ({ page }) => {
|
||||
|
||||
await page.getByRole('row').first().getByRole('button').click();
|
||||
await Promise.all([
|
||||
page.getByRole('button').getByText('Mark as active').first().click(),
|
||||
page.getByRole('menuitem').getByText('Mark as active').first().click(),
|
||||
expect(page.getByText(newTaskName)).not.toBeVisible(),
|
||||
]);
|
||||
await Promise.all([
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
:root.dark {
|
||||
--color-bg-primary: #0f1011;
|
||||
--color-bg-secondary: #17181a;
|
||||
--color-bg-primary: #101012;
|
||||
--color-bg-secondary: #17181B;
|
||||
--color-bg-tertiary: #2A2C32;
|
||||
--color-bg-quaternary: #141518;
|
||||
--color-bg-background: #0B0B0B;
|
||||
--color-bg-background: #090909;
|
||||
--color-text-primary: #ffffff;
|
||||
--color-text-secondary: #e3e4e6;
|
||||
--color-text-tertiary: #969799;
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
--theme-color-menu-active: var(--color-bg-secondary);
|
||||
--theme-color-card-background: var(--color-bg-secondary);
|
||||
--theme-shadow-card: 0 4px 7px 0px rgb(0 0 0 / 30%);
|
||||
--theme-shadow-card: 0 4px 7px 0px rgb(0 0 0 / 15%);
|
||||
--theme-shadow-dropdown: 0 4px 7px 0px rgb(0 0 0 / 40%);
|
||||
|
||||
--theme-color-card-background-active: var(--color-bg-tertiary);
|
||||
|
||||
@@ -266,7 +266,7 @@ const page = usePage<{
|
||||
<BillingBanner v-if="isBillingActivated()" />
|
||||
|
||||
<div
|
||||
class="min-h-screen bg-default-background border-l border-default-background-separator">
|
||||
class="min-h-screen flex flex-col bg-default-background border-l border-default-background-separator">
|
||||
<!-- Page Heading -->
|
||||
<header
|
||||
v-if="$slots.header"
|
||||
@@ -281,7 +281,7 @@ const page = usePage<{
|
||||
</header>
|
||||
|
||||
<!-- Page Content -->
|
||||
<main class="pb-28">
|
||||
<main class="pb-28 flex-1">
|
||||
<slot />
|
||||
|
||||
</main>
|
||||
|
||||
@@ -10,7 +10,6 @@ withDefaults(
|
||||
}
|
||||
);
|
||||
</script>
|
||||
Modal.vue
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
|
||||
@@ -5,18 +5,23 @@ const props = withDefaults(
|
||||
defineProps<{
|
||||
align?: 'center' | 'end' | 'start';
|
||||
closeOnContentClick?: boolean;
|
||||
autoFocus?: boolean;
|
||||
}>(),
|
||||
{
|
||||
align: 'start',
|
||||
closeOnContentClick: true,
|
||||
autoFocus: true,
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(['open', 'submit']);
|
||||
const open = defineModel({ default: false });
|
||||
|
||||
|
||||
|
||||
function handleAutofocus(event: Event) {
|
||||
if (props.autoFocus === false) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function onContentClick() {
|
||||
if (props.closeOnContentClick === true) {
|
||||
@@ -42,6 +47,7 @@ function onOpenChange(value: boolean) {
|
||||
<PopoverContent
|
||||
:align="align"
|
||||
class="rounded-lg overflow-hidden relative border border-card-border overflow-none shadow-dropdown bg-card-background"
|
||||
@open-auto-focus="handleAutofocus"
|
||||
@click="onContentClick">
|
||||
<slot name="content" />
|
||||
</PopoverContent>
|
||||
|
||||
@@ -171,6 +171,7 @@ function closeAndFocusInput() {
|
||||
<Dropdown
|
||||
v-model="open"
|
||||
align="center"
|
||||
:auto-focus="false"
|
||||
:close-on-content-click="false"
|
||||
@submit="open = false">
|
||||
<template #trigger>
|
||||
|
||||
Reference in New Issue
Block a user