-
Notifications
You must be signed in to change notification settings - Fork 331
/
Copy pathindex.ts
127 lines (114 loc) · 4.61 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { createClerkClient as backendCreateClerkClient } from '@clerk/backend';
import type { Browser, BrowserContext, Page, Response } from '@playwright/test';
import { expect } from '@playwright/test';
import type { Application } from '../models/application';
import { createAppPageObject } from './appPageObject';
import { createEmailService } from './emailService';
import { createOrganizationSwitcherComponentPageObject } from './organizationSwitcherPageObject';
import type { EnchancedPage, TestArgs } from './signInPageObject';
import { createSignInComponentPageObject } from './signInPageObject';
import { createSignUpComponentPageObject } from './signUpPageObject';
import { createUserButtonPageObject } from './userButtonPageObject';
import { createUserProfileComponentPageObject } from './userProfilePageObject';
import type { FakeOrganization, FakeUser } from './usersService';
import { createUserService } from './usersService';
export type { FakeUser, FakeOrganization };
const createClerkClient = (app: Application) => {
return backendCreateClerkClient({
apiUrl: app.env.privateVariables.get('CLERK_API_URL'),
secretKey: app.env.privateVariables.get('CLERK_SECRET_KEY'),
publishableKey: app.env.publicVariables.get('CLERK_PUBLISHABLE_KEY'),
});
};
const createExpectPageObject = ({ page }: TestArgs) => {
return {
toBeHandshake: async (res: Response) => {
// Travel the redirect chain until we find the handshake header
// TODO: Loop through the redirects until we find a handshake header, or timeout trying
const redirect = await res.request().redirectedFrom().redirectedFrom().redirectedFrom().response();
expect(redirect.status()).toBe(307);
expect(redirect.headers()['x-clerk-auth-status']).toContain('handshake');
},
toBeSignedOut: () => {
return page.waitForFunction(() => {
return !window.Clerk?.user;
});
},
toBeSignedIn: async () => {
return page.waitForFunction(() => {
return !!window.Clerk?.user;
});
},
};
};
const createClerkUtils = ({ page }: TestArgs) => {
return {
getClientSideUser: () => {
return page.evaluate(() => {
return window.Clerk?.user;
});
},
};
};
type CreateAppPageObjectArgs = { page: Page; context: BrowserContext; browser: Browser };
export const createTestUtils = <
Params extends { app: Application } & Partial<CreateAppPageObjectArgs>,
Services = typeof services,
PO = typeof pageObjects,
BH = typeof browserHelpers,
FullReturn = { services: Services; po: PO; tabs: BH; page: EnchancedPage; nexJsVersion: string },
OnlyAppReturn = { services: Services },
>(
params: Params,
): Params extends Partial<CreateAppPageObjectArgs> ? FullReturn : OnlyAppReturn => {
const { app, context, browser } = params || {};
const clerkClient = createClerkClient(app);
const services = {
email: createEmailService(),
users: createUserService(clerkClient),
clerk: clerkClient,
};
if (!params.page) {
return { services } as any;
}
const page = createAppPageObject({ page: params.page }, app);
const testArgs = { page, context, browser };
const pageObjects = {
signUp: createSignUpComponentPageObject(testArgs),
signIn: createSignInComponentPageObject(testArgs),
userProfile: createUserProfileComponentPageObject(testArgs),
organizationSwitcher: createOrganizationSwitcherComponentPageObject(testArgs),
userButton: createUserButtonPageObject(testArgs),
expect: createExpectPageObject(testArgs),
clerk: createClerkUtils(testArgs),
};
const browserHelpers = {
runInNewTab: async (
cb: (u: { services: Services; po: PO; page: EnchancedPage }, context: BrowserContext) => Promise<unknown>,
) => {
const u = createTestUtils({ app, page: createAppPageObject({ page: await context.newPage() }, app) });
await cb(u as any, context);
return u;
},
runInNewBrowser: async (
cb: (u: { services: Services; po: PO; page: EnchancedPage }, context: BrowserContext) => Promise<unknown>,
) => {
if (!browser) {
throw new Error('Browser is not defined. Did you forget to pass it to createPageObjects?');
}
const context = await browser.newContext();
const u = createTestUtils({ app, page: createAppPageObject({ page: await context.newPage() }, app) });
await cb(u as any, context);
return u;
},
};
return {
page,
services,
po: pageObjects,
tabs: browserHelpers,
// eslint-disable-next-line turbo/no-undeclared-env-vars
nexJsVersion: process.env.E2E_NEXTJS_VERSION,
} as any;
};
export { testAgainstRunningApps } from './testAgainstRunningApps';