{t('404-error')}
13 | 14 |19 | {t('sorry-we-could-not-find-page')} 20 |
21 | 22 |Code Snippet);
42 |
43 | expect(screen.getByText('Code Snippet')).toHaveClass('font-mono');
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/app/components/text.tsx:
--------------------------------------------------------------------------------
1 | import { Link } from '@remix-run/react';
2 | import type { ComponentPropsWithoutRef } from 'react';
3 |
4 | import { cn } from '~/utils/shadcn-ui';
5 |
6 | export function Text({ className, ...props }: ComponentPropsWithoutRef<'p'>) {
7 | return (
8 |
12 | );
13 | }
14 |
15 | export function TextLink({
16 | className,
17 | ...props
18 | }: ComponentPropsWithoutRef
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/public/locales/en/organization-team-members.json:
--------------------------------------------------------------------------------
1 | {
2 | "admin": "Admin",
3 | "admin-description": "Can edit the organization and manage billing.",
4 | "card-description-invite-link": "Invite team members to your organization. You can generate an invite link here. After generating the link, it will be valid for 48 hours. Simply send it to your team members and they will be able to join your organization by clicking it.",
5 | "card-title-invite-link": "Invite team members",
6 | "card-title-members-list": "Members",
7 | "copied": "Copied!",
8 | "copy-invite-link": "Copy invite link to clipboard",
9 | "create-new-invite-link": "Create new invite link",
10 | "creating": "Creating ...",
11 | "deactivate-link": "Deactivate link",
12 | "deactivated": "Deactivated",
13 | "deactivated-description": "Access revoked to everything.",
14 | "deactivating": "Deactivating ...",
15 | "go-to-link": "Go to the invite link's page",
16 | "invite-link-copied": "Invite link copied to clipboard",
17 | "link-valid-until": "Your link is valid until {{date}}.",
18 | "member": "Member",
19 | "member-description": "Access to standard features.",
20 | "new-link-deactivates-old": "Generating a new link automatically deactivates the old one.",
21 | "no-roles-found": "No roles found.",
22 | "owner": "Owner",
23 | "owner-description": "Can assign roles and delete the organization.",
24 | "regenerate-link": "Regenerate link",
25 | "regenerating": "Regenerating ...",
26 | "roles-placeholder": "Select new role ...",
27 | "team-members": "Team members"
28 | }
--------------------------------------------------------------------------------
/templates/playwright/e2e/feature/feature.spec.hbs:
--------------------------------------------------------------------------------
1 | import AxeBuilder from '@axe-core/playwright';
2 | import { expect, test } from '@playwright/test';
3 |
4 | import { deleteUserProfileFromDatabaseById } from '~/features/user-profile/user-profile-model.server';
5 |
6 | import { loginAndSaveUserProfileToDatabase } from '../../utils';
7 |
8 | test.describe('{{feature}} page', () => {
9 | test("given the user is logged out: page redirects you to the login page and remembers the page as the redirectTo query parameter", async ({
10 | page,
11 | baseURL,
12 | }) => {
13 | await page.goto('.{{name}}');
14 | const expectedUrl = new URL(baseURL + '/login');
15 | expectedUrl.searchParams.append('redirectTo', '{{name}}');
16 | expect(page.url()).toEqual(expectedUrl.href);
17 | });
18 |
19 | test('page has the correct title', async ({ page }) => {
20 | await page.goto('.{{name}}');
21 | expect(await page.title()).toEqual('{{titleCase feature}}');
22 | await expect(page.getByRole('heading', { level: 1, name: '{{titleCase feature}}' })).toBeVisible();
23 | });
24 |
25 | test('page should not have any automatically detectable accessibility issues', async ({
26 | page,
27 | }) => {
28 | const { id } = await loginAndSaveUserProfileToDatabase({ page });
29 | await page.goto('.{{name}}');
30 |
31 | const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
32 |
33 | expect(accessibilityScanResults.violations).toEqual([]);
34 |
35 | await deleteUserProfileFromDatabaseById(id);
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/app/features/user-authentication/user-auth-session-factories.server.ts:
--------------------------------------------------------------------------------
1 | import { faker } from '@faker-js/faker';
2 | import { createId } from '@paralleldrive/cuid2';
3 | import type { UserAuthSession } from '@prisma/client';
4 |
5 | import { generateRandomClerkId } from '~/test/generate-random-did.server';
6 | import type { Factory } from '~/utils/types';
7 |
8 | /**
9 | * Creates a user auth session _**without**_ any values. If you want to create a
10 | * user auth session with values, use `createPopulatedUserAuthSession` instead.
11 | *
12 | * @param sessionParams - User auth session params to create session with.
13 | * @returns User auth session with given params.
14 | */
15 | export const createUserAuthSession: Factory45 | {t('accept-invite-instructions')} 46 |
47 | 48 | 57 |