2021-10-13 13:26:56 +00:00
|
|
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
|
|
import { provider, Provider } from "kont";
|
2021-10-17 00:11:37 +00:00
|
|
|
import { Page, Cookie } from "playwright";
|
2021-10-13 13:26:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Context data that Login provder needs.
|
|
|
|
*/
|
|
|
|
export type Needs = {};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Login provider's options.
|
|
|
|
*/
|
|
|
|
export type Params = {
|
|
|
|
user: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Context data that Page provider contributes.
|
|
|
|
*/
|
|
|
|
export type Contributes = {
|
|
|
|
page: Page;
|
|
|
|
};
|
|
|
|
|
2021-10-17 00:11:37 +00:00
|
|
|
const cookieCache = new Map<string, Cookie[]>();
|
2021-10-13 13:26:56 +00:00
|
|
|
/**
|
|
|
|
* Creates a new context / "incognito tab" and logs in the specified user
|
|
|
|
*/
|
|
|
|
export function loginProvider(opts: {
|
|
|
|
user: string;
|
|
|
|
/**
|
|
|
|
* Path to navigate to after login
|
|
|
|
*/
|
|
|
|
path?: string;
|
|
|
|
/**
|
|
|
|
* Selector to wait for to decide that the navigation is done
|
|
|
|
*/
|
|
|
|
waitForSelector?: string;
|
|
|
|
}): Provider<Needs, Contributes> {
|
|
|
|
return provider<Needs, Contributes>()
|
2021-10-18 21:07:06 +00:00
|
|
|
.name("login")
|
2021-10-13 13:26:56 +00:00
|
|
|
.before(async () => {
|
|
|
|
const context = await browser.newContext();
|
|
|
|
const page = await context.newPage();
|
2021-10-17 00:11:37 +00:00
|
|
|
const cachedCookies = cookieCache.get(opts.user);
|
|
|
|
if (cachedCookies) {
|
|
|
|
await context.addCookies(cachedCookies);
|
|
|
|
} else {
|
2021-11-08 14:10:02 +00:00
|
|
|
await page.goto("http://localhost:3000/auth/login");
|
2021-10-17 00:11:37 +00:00
|
|
|
// Click input[name="email"]
|
|
|
|
await page.click('input[name="email"]');
|
|
|
|
// Fill input[name="email"]
|
|
|
|
await page.fill('input[name="email"]', `${opts.user}@example.com`);
|
|
|
|
// Press Tab
|
|
|
|
await page.press('input[name="email"]', "Tab");
|
|
|
|
// Fill input[name="password"]
|
|
|
|
await page.fill('input[name="password"]', opts.user);
|
|
|
|
// Press Enter
|
|
|
|
await page.press('input[name="password"]', "Enter");
|
2021-10-13 13:26:56 +00:00
|
|
|
|
2021-11-08 14:10:02 +00:00
|
|
|
await page.waitForNavigation({
|
|
|
|
url(url) {
|
|
|
|
return !url.pathname.startsWith("/auth");
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2021-10-17 00:11:37 +00:00
|
|
|
const cookies = await context.cookies();
|
|
|
|
cookieCache.set(opts.user, cookies);
|
|
|
|
}
|
2021-10-13 13:26:56 +00:00
|
|
|
|
|
|
|
if (opts.path) {
|
|
|
|
await page.goto(`http://localhost:3000${opts.path}`);
|
|
|
|
}
|
|
|
|
if (opts.waitForSelector) {
|
|
|
|
await page.waitForSelector(opts.waitForSelector);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
page,
|
|
|
|
context,
|
|
|
|
};
|
|
|
|
})
|
|
|
|
.after(async (ctx) => {
|
|
|
|
await ctx.page?.close();
|
|
|
|
await ctx.context?.close();
|
|
|
|
})
|
|
|
|
.done();
|
|
|
|
}
|