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