Merge branch 'main' into fix/after-meeting-ends-migration
This commit is contained in:
commit
95bc9625bd
|
@ -1,7 +1,7 @@
|
|||
name: E2E App-Store Apps
|
||||
on:
|
||||
push:
|
||||
branches: [ feature/event-routing ]
|
||||
branches: [fixes/e2e-consolidation] # TODO: Remove this after merged in main
|
||||
pull_request_target: # So we can test on forks
|
||||
branches:
|
||||
- main
|
||||
|
@ -86,14 +86,14 @@ jobs:
|
|||
restore-keys: cache-playwright-
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Install playwright deps
|
||||
# if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run Tests
|
||||
run: yarn app-e2e-quick
|
||||
run: yarn test-e2e:app-store
|
||||
|
||||
- name: Upload Test Results
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: test-results-core
|
||||
path: packages/app-store/**/playwright/results
|
||||
path: packages/app-store/**/playwright/results
|
||||
|
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
restore-keys: cache-playwright-
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Install playwright deps
|
||||
# if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run Tests
|
||||
run: yarn turbo run embed-tests-update-snapshots:ci --scope=@calcom/embed-react --concurrency=1
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
name: E2E test
|
||||
on:
|
||||
push:
|
||||
branches: [fixes/e2e-consolidation] # TODO: Remove this after merged in main
|
||||
pull_request_target: # So we can test on forks
|
||||
branches:
|
||||
- main
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
name: E2E Test - Integrations with Third Party
|
||||
on:
|
||||
push:
|
||||
branches: [ tests/with-msw ]
|
||||
pull_request_target: # So we can test on forks
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- apps/api/**
|
||||
- apps/console/**
|
||||
- apps/docs/**
|
||||
- apps/swagger/**
|
||||
- apps/website/**
|
||||
- apps/web/public/**
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 20
|
||||
name: E2E Integration
|
||||
strategy:
|
||||
matrix:
|
||||
node: ["16.x"]
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
|
||||
NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000
|
||||
NEXT_PUBLIC_WEBSITE_URL: http://localhost:3000
|
||||
NEXTAUTH_SECRET: secret
|
||||
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
|
||||
GOOGLE_LOGIN_ENABLED: true
|
||||
# CRON_API_KEY: xxx
|
||||
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
|
||||
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_PUBLIC_KEY }}
|
||||
STRIPE_PRIVATE_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }}
|
||||
STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }}
|
||||
STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }}
|
||||
PAYMENT_FEE_PERCENTAGE: 0.005
|
||||
PAYMENT_FEE_FIXED: 10
|
||||
SAML_DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
|
||||
SAML_ADMINS: pro@example.com
|
||||
NEXTAUTH_URL: http://localhost:3000/api/auth
|
||||
ZOOM_CLIENT_ID: ZOOM_CLIENT_ID
|
||||
ZOOM_CLIENT_SECRET: ZOOM_CLIENT_SECRET
|
||||
HUBSPOT_CLIENT_ID: HUBSPOT_CLIENT_ID
|
||||
HUBSPOT_CLIENT_SECRET: HUBSPOT_CLIENT_SECRET
|
||||
NEXT_PUBLIC_IS_E2E: 1
|
||||
# EMAIL_FROM: e2e@cal.com
|
||||
# EMAIL_SERVER_HOST: ${{ secrets.CI_EMAIL_SERVER_HOST }}
|
||||
# EMAIL_SERVER_PORT: ${{ secrets.CI_EMAIL_SERVER_PORT }}
|
||||
# EMAIL_SERVER_USER: ${{ secrets.CI_EMAIL_SERVER_USER }}
|
||||
# EMAIL_SERVER_PASSWORD: ${{ secrets.CI_EMAIL_SERVER_PASSWORD }}
|
||||
# MS_GRAPH_CLIENT_ID: xxx
|
||||
# MS_GRAPH_CLIENT_SECRET: xxx
|
||||
# ZOOM_CLIENT_ID: xxx
|
||||
# ZOOM_CLIENT_SECRET: xxx
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:12.1
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: calendso
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
|
||||
fetch-depth: 2
|
||||
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
|
||||
- name: Use Node ${{ matrix.node }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: "yarn"
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@v2
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/ms-playwright
|
||||
~/.cache/ms-playwright
|
||||
${{ github.workspace }}/node_modules/playwright
|
||||
key: cache-playwright-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: cache-playwright-
|
||||
- run: yarn --frozen-lockfile
|
||||
- name: Install playwright deps
|
||||
# if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run Tests
|
||||
# Force bypass cache because new environment variables were added that caused DB to change but build remains cached
|
||||
run: yarn test-e2e-integrations --force
|
||||
|
||||
- name: Upload Test Results
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: test-results-core
|
||||
path: apps/web/playwright-integrations/test-results
|
|
@ -1,5 +1,7 @@
|
|||
name: "Meta Workflow: Require Conditional Status Checks"
|
||||
on:
|
||||
push:
|
||||
branches: [fixes/e2e-consolidation] # TODO: Remove this after merged in main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
@ -34,3 +36,7 @@ jobs:
|
|||
paths:
|
||||
- /apps/web/**
|
||||
- /packages/embeds/**
|
||||
- job: test
|
||||
paths:
|
||||
- /apps/web/**
|
||||
- /packages/**
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
name: Unit tests
|
||||
on:
|
||||
push:
|
||||
branches: [fixes/e2e-consolidation] # TODO: Remove this after merged in main
|
||||
pull_request_target: # So we can test on forks
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- apps/web/**
|
||||
- packages/**
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 20
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
|
||||
fetch-depth: 2
|
||||
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
|
||||
- name: Use Node 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: "yarn"
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn test
|
|
@ -207,7 +207,7 @@ Be sure to set the environment variable `NEXTAUTH_URL` to the correct value. If
|
|||
yarn test-e2e
|
||||
|
||||
# To open last HTML report run:
|
||||
yarn workspace @calcom/web playwright-report
|
||||
yarn playwright show-report test-results/reports/playwright-html-report
|
||||
```
|
||||
|
||||
### Upgrading from earlier versions
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
|
||||
"dev": "next dev",
|
||||
"dx": "yarn dev",
|
||||
"test-e2e": "NEXT_PUBLIC_IS_E2E=1 yarn playwright test --config=../../tests/config/playwright.config.ts --project=chromium",
|
||||
"test-e2e-integrations": "NEXT_PUBLIC_IS_E2E=1 yarn playwright test --config=playwright-integrations/config/playwright.config.ts --project=chromium",
|
||||
"test-e2e-integrations-quick": "QUICK=true E2E_DEV_SERVER=1 yarn test-e2e-integrations",
|
||||
"db-setup-tests": "dotenv -e ./test/.env.test -- yarn workspace @calcom/prisma prisma generate",
|
||||
"playwright-report": "playwright show-report playwright/reports/playwright-html-report",
|
||||
"test-codegen": "yarn playwright codegen http://localhost:3000",
|
||||
"type-check": "tsc --pretty --noEmit",
|
||||
"build": "next build",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
test-results
|
|
@ -1,68 +0,0 @@
|
|||
import { devices, PlaywrightTestConfig } from "@playwright/test";
|
||||
import dotenv from "dotenv";
|
||||
import { addAliases } from "module-alias";
|
||||
import * as path from "path";
|
||||
|
||||
dotenv.config({ path: "./env" });
|
||||
|
||||
// Add aliases for the paths specified in the tsconfig.json file.
|
||||
// This is needed because playwright does not consider tsconfig.json
|
||||
// For more info, see:
|
||||
// https://stackoverflow.com/questions/69023682/typescript-playwright-error-cannot-find-module
|
||||
// https://github.com/microsoft/playwright/issues/7066#issuecomment-983984496
|
||||
addAliases({
|
||||
"@components": __dirname + "/apps/web/components",
|
||||
"@lib": __dirname + "/apps/web/lib",
|
||||
"@server": __dirname + "/apps/web/server",
|
||||
"@ee": __dirname + "/apps/web/ee",
|
||||
});
|
||||
|
||||
const outputDir = path.join(__dirname, "..", "test-results");
|
||||
const testDir = path.join(__dirname, "..", "tests");
|
||||
|
||||
const DEFAULT_NAVIGATION_TIMEOUT = 600000;
|
||||
|
||||
const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS;
|
||||
process.env.PLAYWRIGHT_TEST_BASE_URL = "http://localhost:3000";
|
||||
const quickMode = process.env.QUICK === "true";
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: 0,
|
||||
workers: quickMode ? 1 : 1,
|
||||
timeout: 60_000,
|
||||
maxFailures: headless ? 10 : undefined,
|
||||
reporter: [
|
||||
[process.env.CI ? "github" : "list"],
|
||||
["html", { outputFolder: path.join(outputDir, "reports/playwright-html-report"), open: "never" }],
|
||||
["junit", { outputFile: path.join(outputDir, "reports/results.xml") }],
|
||||
],
|
||||
outputDir,
|
||||
use: {
|
||||
baseURL: "http://localhost:3000/",
|
||||
locale: "en-US",
|
||||
trace: "retain-on-failure",
|
||||
headless,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
testDir,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
/** If navigation takes more than this, then something's wrong, let's fail fast. */
|
||||
navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
/* {
|
||||
name: "firefox",
|
||||
use: { ...devices["Desktop Firefox"] },
|
||||
},
|
||||
{
|
||||
name: "webkit",
|
||||
use: { ...devices["Desktop Safari"] },
|
||||
}, */
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -1,51 +0,0 @@
|
|||
import { test as base } from "@playwright/test";
|
||||
import { Server } from "http";
|
||||
import { rest } from "msw";
|
||||
import type { SetupServerApi } from "msw/node";
|
||||
|
||||
import { nextServer } from "../../playwright-integrations/next-server";
|
||||
import { createBookingsFixture } from "../../playwright/fixtures/bookings";
|
||||
import { createPaymentsFixture } from "../../playwright/fixtures/payments";
|
||||
import { createUsersFixture } from "../../playwright/fixtures/users";
|
||||
|
||||
interface Fixtures {
|
||||
users: ReturnType<typeof createUsersFixture>;
|
||||
bookings: ReturnType<typeof createBookingsFixture>;
|
||||
payments: ReturnType<typeof createPaymentsFixture>;
|
||||
server: Server;
|
||||
requestInterceptor: SetupServerApi;
|
||||
rest: typeof rest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://playwright.dev/docs/test-fixtures
|
||||
*/
|
||||
export const test = base.extend<Fixtures>({
|
||||
users: async ({ page }, use, workerInfo) => {
|
||||
const usersFixture = createUsersFixture(page, workerInfo);
|
||||
await use(usersFixture);
|
||||
},
|
||||
bookings: async ({ page }, use) => {
|
||||
const bookingsFixture = createBookingsFixture(page);
|
||||
await use(bookingsFixture);
|
||||
},
|
||||
payments: async ({ page }, use) => {
|
||||
const payemntsFixture = createPaymentsFixture(page);
|
||||
await use(payemntsFixture);
|
||||
},
|
||||
// This fixture runs for each worker, ensuring that every worker starts it's own Next.js instance on which we can attach MSW
|
||||
// A single worker can run many tests
|
||||
server: [
|
||||
async ({}, use) => {
|
||||
const server = await nextServer();
|
||||
await use(server);
|
||||
server.close();
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
scope: "worker",
|
||||
auto: true,
|
||||
},
|
||||
],
|
||||
});
|
|
@ -5,13 +5,15 @@ import { test } from "./lib/fixtures";
|
|||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("App Store - Authed", () => {
|
||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||
test("Browse apple-calendar and try to install", async ({ page }) => {
|
||||
test("Browse apple-calendar and try to install", async ({ page, users }) => {
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
await page.goto("/apps");
|
||||
await page.click('[data-testid="app-store-category-calendar"]');
|
||||
await page.click('[data-testid="app-store-app-card-apple-calendar"]');
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
await expect(page.locator(`text=Connect to Apple Server`)).toBeVisible();
|
||||
await pro.delete();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
import { expect } from "@playwright/test";
|
||||
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
|
||||
import { test } from "../lib/fixtures";
|
||||
import { todo } from "../lib/testUtils";
|
||||
|
||||
test.describe("Can signup from a team invite", async () => {
|
||||
test.beforeEach(async ({ users }) => {
|
||||
const proUser = await users.create();
|
||||
await proUser.login();
|
||||
});
|
||||
test.afterEach(async ({ users }) => users.deleteAll());
|
||||
|
||||
test("Team invites validations work and can accept invite", async ({ browser, page, users, prisma }) => {
|
||||
const [proUser] = users.get();
|
||||
const teamName = `${proUser.username}'s Team`;
|
||||
const testUser = {
|
||||
username: `${proUser.username}-member`,
|
||||
password: `${proUser.username}-member`,
|
||||
email: `${proUser.username}-member@example.com`,
|
||||
};
|
||||
await page.goto("/settings/teams");
|
||||
|
||||
// Create a new team
|
||||
await page.click("text=New Team");
|
||||
await page.fill('input[id="name"]', teamName);
|
||||
await page.click('[data-testid="create-new-team-button"]');
|
||||
// Go to new team page
|
||||
await page.click(`a[title="${teamName}"]`);
|
||||
// Add new member to team
|
||||
await page.click('[data-testid="new-member-button"]');
|
||||
await page.fill('input[id="inviteUser"]', testUser.email);
|
||||
await page.click('[data-testid="invite-new-member-button"]');
|
||||
|
||||
// Wait for the invite to be sent
|
||||
await page.waitForSelector(`[data-testid="member-email"][data-email="${testUser.email}"]`);
|
||||
|
||||
const tokenObj = await prisma.verificationToken.findFirstOrThrow({
|
||||
where: { identifier: testUser.email },
|
||||
select: { token: true },
|
||||
});
|
||||
|
||||
if (!proUser.username) throw Error("Test username is null, can't continue");
|
||||
|
||||
// Open a new user window to accept the invite
|
||||
const newPage = await browser.newPage();
|
||||
await newPage.goto(`/auth/signup?token=${tokenObj.token}&callbackUrl=${WEBAPP_URL}/settings/teams`);
|
||||
|
||||
// Fill in form
|
||||
await newPage.fill('input[name="username"]', proUser.username); // Invalid username
|
||||
await newPage.fill('input[name="email"]', testUser.email);
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
|
||||
await expect(newPage.locator('text="Username already taken"')).toBeVisible();
|
||||
|
||||
// Email address is already registered
|
||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||
await newPage.reload();
|
||||
await newPage.fill('input[name="username"]', testUser.username);
|
||||
await newPage.fill('input[name="email"]', `${proUser.username}@example.com`); // Taken email
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
await expect(newPage.locator('text="Email address is already registered"')).toBeVisible();
|
||||
|
||||
// Successful signup
|
||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||
await newPage.reload();
|
||||
await newPage.fill('input[name="username"]', testUser.username);
|
||||
await newPage.fill('input[name="email"]', testUser.email);
|
||||
await newPage.fill('input[name="password"]', testUser.password);
|
||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
await expect(newPage.locator(`[data-testid="login-form"]`)).toBeVisible();
|
||||
|
||||
// We don't need the new browser anymore
|
||||
await newPage.close();
|
||||
|
||||
const createdUser = await prisma.user.findUniqueOrThrow({
|
||||
where: { email: testUser.email },
|
||||
include: { teams: { include: { team: true } } },
|
||||
});
|
||||
|
||||
console.log("createdUser", createdUser);
|
||||
|
||||
// Check that the user was created
|
||||
expect(createdUser).not.toBeNull();
|
||||
expect(createdUser.username).toBe(testUser.username);
|
||||
expect(createdUser.password).not.toBeNull();
|
||||
expect(createdUser.emailVerified).not.toBeNull();
|
||||
// Check that the user accepted the team invite
|
||||
expect(createdUser.teams).toHaveLength(1);
|
||||
expect(createdUser.teams[0].team.name).toBe(teamName);
|
||||
expect(createdUser.teams[0].role).toBe("MEMBER");
|
||||
expect(createdUser.teams[0].accepted).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
todo("Can login using 2FA");
|
|
@ -1,120 +0,0 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { WEBAPP_URL } from "@lib/config/constants";
|
||||
|
||||
import { todo } from "../lib/testUtils";
|
||||
|
||||
test.describe("Can signup from a team invite", async () => {
|
||||
let page;
|
||||
let token: string | undefined;
|
||||
let signupFromInviteURL = "";
|
||||
const team = { name: "Seeded Team", slug: "seeded-team" };
|
||||
const testUser = {
|
||||
email: "test@test.com",
|
||||
password: "secretpassword123",
|
||||
validUsername: "test-user",
|
||||
};
|
||||
const usernameAlreadyTaken = "teampro";
|
||||
const emailAlreadyTaken = "teampro@example.com";
|
||||
|
||||
test.use({ storageState: "playwright/artifacts/teamproStorageState.json" });
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
page = await browser.newPage();
|
||||
|
||||
await page.goto("/settings/teams");
|
||||
|
||||
await page.waitForSelector(`a[title="${team.name}"]`);
|
||||
await page.click(`a[title="${team.name}"]`);
|
||||
|
||||
// Send invite to team
|
||||
await page.click('[data-testid="new-member-button"]');
|
||||
await page.fill('input[id="inviteUser"]', testUser.email);
|
||||
await page.click('[data-testid="invite-new-member-button"]');
|
||||
|
||||
// Wait for the invite to be sent
|
||||
await page.waitForSelector(`[data-testid="member-email"][data-email="${testUser.email}"]`);
|
||||
|
||||
const tokenObj = await prisma.verificationToken.findFirst({
|
||||
where: { identifier: testUser.email },
|
||||
select: { token: true },
|
||||
});
|
||||
token = tokenObj?.token;
|
||||
signupFromInviteURL = `/auth/signup?token=${token}&callbackUrl=${WEBAPP_URL}/settings/teams`;
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
// Delete test user
|
||||
await prisma.user.delete({
|
||||
where: { email: testUser.email },
|
||||
});
|
||||
// Delete verification request
|
||||
await prisma.verificationToken.delete({
|
||||
where: { token },
|
||||
});
|
||||
});
|
||||
|
||||
test("Username already taken", async ({ page }) => {
|
||||
expect(token).toBeDefined();
|
||||
await page.goto(signupFromInviteURL);
|
||||
// Fill in form
|
||||
await page.fill('input[name="username"]', usernameAlreadyTaken);
|
||||
await page.fill('input[name="email"]', testUser.email);
|
||||
await page.fill('input[name="password"]', testUser.password);
|
||||
await page.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await page.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
|
||||
await expect(page.locator('text="Username already taken"')).toBeVisible();
|
||||
});
|
||||
|
||||
test("Email address is already registered", async ({ page }) => {
|
||||
expect(token).toBeDefined();
|
||||
await page.goto(signupFromInviteURL);
|
||||
// Fill in form
|
||||
await page.fill('input[name="username"]', testUser.validUsername);
|
||||
await page.fill('input[name="email"]', emailAlreadyTaken);
|
||||
await page.fill('input[name="password"]', testUser.password);
|
||||
await page.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await page.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
|
||||
await expect(page.locator('text="Email address is already registered"')).toBeVisible();
|
||||
});
|
||||
|
||||
test("Successful signup", async ({ page }) => {
|
||||
expect(token).toBeDefined();
|
||||
await page.goto(signupFromInviteURL);
|
||||
// Fill in form
|
||||
await page.fill('input[name="username"]', testUser.validUsername);
|
||||
await page.fill('input[name="email"]', testUser.email);
|
||||
await page.fill('input[name="password"]', testUser.password);
|
||||
await page.fill('input[name="passwordcheck"]', testUser.password);
|
||||
await page.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||
|
||||
await page.waitForNavigation();
|
||||
|
||||
const createdUser = await prisma.user.findUnique({
|
||||
where: { email: testUser.email },
|
||||
include: {
|
||||
teams: {
|
||||
include: {
|
||||
team: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
// Check that the user was created
|
||||
expect(createdUser).not.toBeNull();
|
||||
expect(createdUser?.username).toBe(testUser.validUsername);
|
||||
expect(createdUser?.password).not.toBeNull();
|
||||
expect(createdUser?.emailVerified).not.toBeNull();
|
||||
// Check that the user accepted the team invite
|
||||
expect(createdUser?.teams).toHaveLength(1);
|
||||
expect(createdUser?.teams[0].team.name).toBe(team.name);
|
||||
expect(createdUser?.teams[0].team.slug).toBe(team.slug);
|
||||
expect(createdUser?.teams[0].role).toBe("MEMBER");
|
||||
expect(createdUser?.teams[0].accepted).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
todo("Can login using 2FA");
|
|
@ -0,0 +1,23 @@
|
|||
import { expect } from "@playwright/test";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
test.describe("Change Passsword Test", () => {
|
||||
test("change password", async ({ page, users }) => {
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
// Go to http://localhost:3000/settings/security
|
||||
await page.goto("/settings/security");
|
||||
|
||||
if (!pro.username) throw Error("Test user doesn't have a username");
|
||||
|
||||
// Fill form
|
||||
await page.fill('[name="current_password"]', pro.username);
|
||||
await page.fill('[name="new_password"]', `${pro.username}1111`);
|
||||
await page.press('[name="new_password"]', "Enter");
|
||||
|
||||
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
||||
});
|
||||
});
|
|
@ -1,30 +0,0 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test.describe("Change Passsword Test", () => {
|
||||
// Using logged in state from globalSteup
|
||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||
|
||||
test("change password", async ({ page }) => {
|
||||
// Try to go homepage
|
||||
await page.goto("/");
|
||||
// It should redirect you to the event-types page
|
||||
await page.waitForSelector("[data-testid=event-types]");
|
||||
|
||||
// Go to http://localhost:3000/settings/security
|
||||
await page.goto("/settings/security");
|
||||
|
||||
// Fill form
|
||||
await page.fill('[name="current_password"]', "pro");
|
||||
await page.fill('[name="new_password"]', "pro1");
|
||||
await page.press('[name="new_password"]', "Enter");
|
||||
|
||||
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
||||
|
||||
// Let's revert back to prevent errors on other tests
|
||||
await page.fill('[name="current_password"]', "pro1");
|
||||
await page.fill('[name="new_password"]', "pro");
|
||||
await page.press('[name="new_password"]', "Enter");
|
||||
|
||||
await expect(page.locator(`text=Your password has been successfully changed.`)).toBeVisible();
|
||||
});
|
||||
});
|
|
@ -5,7 +5,6 @@ import { getFreePlanPrice, getProPlanPrice } from "@calcom/app-store/stripepayme
|
|||
import dayjs from "@calcom/dayjs";
|
||||
import stripe from "@calcom/features/ee/payments/server/stripe";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
|
@ -26,7 +25,7 @@ test.describe("Change username on settings", () => {
|
|||
await users.deleteAll();
|
||||
});
|
||||
|
||||
test("User can change username", async ({ page, users }) => {
|
||||
test("User can change username", async ({ page, users, prisma }) => {
|
||||
const user = await users.create({ plan: UserPlan.TRIAL });
|
||||
|
||||
await user.login();
|
||||
|
@ -45,12 +44,12 @@ test.describe("Change username on settings", () => {
|
|||
page.click("[data-testid=save-username]"),
|
||||
]);
|
||||
|
||||
const newUpdatedUser = await prisma.user.findFirst({
|
||||
const newUpdatedUser = await prisma.user.findUniqueOrThrow({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
expect(newUpdatedUser?.username).toBe("demousernamex");
|
||||
expect(newUpdatedUser.username).toBe("demousernamex");
|
||||
});
|
||||
|
||||
test("User trial can update to PREMIUM username", async ({ page, users }, testInfo) => {
|
|
@ -11,7 +11,6 @@ import {
|
|||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("dynamic booking", () => {
|
||||
test.skip(true, "TODO: Re-enable after v1.7 launch");
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
|
@ -19,7 +18,7 @@ test.describe("dynamic booking", () => {
|
|||
await page.goto(`/${pro.username}+${free.username}`);
|
||||
});
|
||||
|
||||
test.afterEach(async ({ page, users }) => {
|
||||
test.afterEach(async ({ users }) => {
|
||||
await users.deleteAll();
|
||||
});
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
import { expect, Page, test } from "@playwright/test";
|
||||
import { expect, Page } from "@playwright/test";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
function chooseEmbedType(page: Page, embedType: string) {
|
||||
page.locator(`[data-testid=${embedType}]`).click();
|
||||
|
@ -86,14 +88,18 @@ async function expectToContainValidPreviewIframe(
|
|||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Embed Code Generator Tests", () => {
|
||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||
test.beforeEach(async ({ users }) => {
|
||||
const pro = await users.create();
|
||||
await pro.login();
|
||||
});
|
||||
|
||||
test.describe("Event Types Page", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/event-types");
|
||||
});
|
||||
|
||||
test("open Embed Dialog and choose Inline for First Event Type", async ({ page }) => {
|
||||
test("open Embed Dialog and choose Inline for First Event Type", async ({ page, users }) => {
|
||||
const [pro] = users.get();
|
||||
const embedUrl = await clickFirstEventTypeEmbedButton(page);
|
||||
await expectToBeNavigatingToEmbedTypesDialog(page, {
|
||||
embedUrl,
|
||||
|
@ -112,10 +118,15 @@ test.describe("Embed Code Generator Tests", () => {
|
|||
|
||||
await gotToPreviewTab(page);
|
||||
|
||||
await expectToContainValidPreviewIframe(page, { embedType: "inline", calLink: "pro/30min" });
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "inline",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
});
|
||||
});
|
||||
|
||||
test("open Embed Dialog and choose floating-popup for First Event Type", async ({ page }) => {
|
||||
test("open Embed Dialog and choose floating-popup for First Event Type", async ({ page, users }) => {
|
||||
const [pro] = users.get();
|
||||
|
||||
const embedUrl = await clickFirstEventTypeEmbedButton(page);
|
||||
|
||||
await expectToBeNavigatingToEmbedTypesDialog(page, {
|
||||
|
@ -133,10 +144,14 @@ test.describe("Embed Code Generator Tests", () => {
|
|||
await expectToContainValidCode(page, { embedType: "floating-popup" });
|
||||
|
||||
await gotToPreviewTab(page);
|
||||
await expectToContainValidPreviewIframe(page, { embedType: "floating-popup", calLink: "pro/30min" });
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "floating-popup",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
});
|
||||
});
|
||||
|
||||
test("open Embed Dialog and choose element-click for First Event Type", async ({ page }) => {
|
||||
test("open Embed Dialog and choose element-click for First Event Type", async ({ page, users }) => {
|
||||
const [pro] = users.get();
|
||||
const embedUrl = await clickFirstEventTypeEmbedButton(page);
|
||||
|
||||
await expectToBeNavigatingToEmbedTypesDialog(page, {
|
||||
|
@ -154,7 +169,10 @@ test.describe("Embed Code Generator Tests", () => {
|
|||
await expectToContainValidCode(page, { embedType: "element-click" });
|
||||
|
||||
await gotToPreviewTab(page);
|
||||
await expectToContainValidPreviewIframe(page, { embedType: "element-click", calLink: "pro/30min" });
|
||||
await expectToContainValidPreviewIframe(page, {
|
||||
embedType: "element-click",
|
||||
calLink: `${pro.username}/30-min`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,25 +1,23 @@
|
|||
import { expect, Locator, test } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { randomString } from "../lib/random";
|
||||
import { deleteEventTypeByTitle } from "./lib/teardown";
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Event Types tests", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/event-types");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
});
|
||||
|
||||
test.describe("pro user", () => {
|
||||
let isCreated: Locator;
|
||||
let eventTitle: string;
|
||||
|
||||
test.afterAll(async () => {
|
||||
if (isCreated) await deleteEventTypeByTitle(eventTitle);
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const proUser = await users.create();
|
||||
await proUser.login();
|
||||
await page.goto("/event-types");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
});
|
||||
|
||||
test.afterEach(async ({ users }) => {
|
||||
await users.deleteAll();
|
||||
});
|
||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||
|
||||
test("has at least 2 events", async ({ page }) => {
|
||||
const $eventTypes = page.locator("[data-testid=event-types] > *");
|
||||
|
@ -34,7 +32,7 @@ test.describe("Event Types tests", () => {
|
|||
test("can add new event type", async ({ page }) => {
|
||||
await page.click("[data-testid=new-event-type]");
|
||||
const nonce = randomString(3);
|
||||
eventTitle = `hello ${nonce}`;
|
||||
const eventTitle = `hello ${nonce}`;
|
||||
|
||||
await page.fill("[name=title]", eventTitle);
|
||||
await page.fill("[name=length]", "10");
|
||||
|
@ -47,15 +45,13 @@ test.describe("Event Types tests", () => {
|
|||
});
|
||||
|
||||
await page.goto("/event-types");
|
||||
|
||||
isCreated = page.locator(`text='${eventTitle}'`);
|
||||
await expect(isCreated).toBeVisible();
|
||||
await expect(page.locator(`text='${eventTitle}'`)).toBeVisible();
|
||||
});
|
||||
|
||||
test("enabling recurring event comes with default options", async ({ page }) => {
|
||||
await page.click("[data-testid=new-event-type]");
|
||||
const nonce = randomString(3);
|
||||
eventTitle = `my recurring event ${nonce}`;
|
||||
const eventTitle = `my recurring event ${nonce}`;
|
||||
|
||||
await page.fill("[name=title]", eventTitle);
|
||||
await page.fill("[name=length]", "15");
|
||||
|
@ -70,8 +66,7 @@ test.describe("Event Types tests", () => {
|
|||
await page.click("[data-testid=show-advanced-settings]");
|
||||
await expect(page.locator("[data-testid=recurring-event-collapsible]")).not.toBeVisible();
|
||||
await page.click("[data-testid=recurring-event-check]");
|
||||
isCreated = page.locator("[data-testid=recurring-event-collapsible]");
|
||||
await expect(isCreated).toBeVisible();
|
||||
await expect(page.locator("[data-testid=recurring-event-collapsible]")).toBeVisible();
|
||||
|
||||
expect(
|
||||
await page
|
||||
|
@ -91,8 +86,12 @@ test.describe("Event Types tests", () => {
|
|||
});
|
||||
|
||||
test("can duplicate an existing event type", async ({ page }) => {
|
||||
// TODO: Locate the actual EventType available in list. This ID might change in future
|
||||
const eventTypeId = "6";
|
||||
const firstElement = await page.waitForSelector(
|
||||
'[data-testid="event-types"] a[href^="/event-types/"] >> nth=0'
|
||||
);
|
||||
const href = await firstElement.getAttribute("href");
|
||||
if (!href) throw new Error("No href found for event type");
|
||||
const [eventTypeId] = href.split("/").reverse();
|
||||
const firstTitle = await page.locator(`[data-testid=event-type-title-${eventTypeId}]`).innerText();
|
||||
const firstFullSlug = await page.locator(`[data-testid=event-type-slug-${eventTypeId}]`).innerText();
|
||||
const firstSlug = firstFullSlug.split("/")[2];
|
||||
|
@ -134,7 +133,13 @@ test.describe("Event Types tests", () => {
|
|||
});
|
||||
|
||||
test.describe("free user", () => {
|
||||
test.use({ storageState: "playwright/artifacts/freeStorageState.json" });
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const free = await users.create({ plan: "FREE" });
|
||||
await free.login();
|
||||
await page.goto("/event-types");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
});
|
||||
|
||||
test("has at least 2 events where first is enabled", async ({ page }) => {
|
||||
const $eventTypes = page.locator("[data-testid=event-types] > *");
|
|
@ -0,0 +1,81 @@
|
|||
import type { Page } from "@playwright/test";
|
||||
|
||||
export const createEmbedsFixture = (page: Page) => {
|
||||
return async (calNamespace: string) => {
|
||||
await page.addInitScript(
|
||||
({ calNamespace }: { calNamespace: string }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
window.eventsFiredStoreForPlaywright = window.eventsFiredStoreForPlaywright || {};
|
||||
document.addEventListener("DOMContentLoaded", function tryAddingListener() {
|
||||
if (parent !== window) {
|
||||
// Firefox seems to execute this snippet for iframe as well. Avoid that. It must be executed only for parent frame.
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
window.initialBodyDisplay = document.body.style.display;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
window.initialBodyBackground = document.body.style.background;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
window.initialValuesSet = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
let api = window.Cal;
|
||||
|
||||
if (!api) {
|
||||
setTimeout(tryAddingListener, 500);
|
||||
return;
|
||||
}
|
||||
if (calNamespace) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
api = window.Cal.ns[calNamespace];
|
||||
}
|
||||
console.log("PlaywrightTest:", "Adding listener for __iframeReady");
|
||||
if (!api) {
|
||||
throw new Error(`namespace "${calNamespace}" not found`);
|
||||
}
|
||||
api("on", {
|
||||
action: "*",
|
||||
callback: (e: any) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
window.iframeReady = true; // Technically if there are multiple cal embeds, it can be set due to some other iframe. But it works for now. Improve it when it doesn't work
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const store = window.eventsFiredStoreForPlaywright;
|
||||
const eventStore = (store[`${e.detail.type}-${e.detail.namespace}`] =
|
||||
store[`${e.detail.type}-${e.detail.namespace}`] || []);
|
||||
eventStore.push(e.detail);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
{ calNamespace }
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const createGetActionFiredDetails = (page: Page) => {
|
||||
return async ({ calNamespace, actionType }: { calNamespace: string; actionType: string }) => {
|
||||
if (!page.isClosed()) {
|
||||
return await page.evaluate(
|
||||
({ actionType, calNamespace }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
//@ts-ignore
|
||||
return window.eventsFiredStoreForPlaywright[`${actionType}-${calNamespace}`];
|
||||
},
|
||||
{ actionType, calNamespace }
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
import type { Server } from "http";
|
||||
|
||||
import { nextServer } from "../lib/next-server";
|
||||
|
||||
type ServerFixture = ReturnType<typeof createServerFixture>;
|
||||
|
||||
// creates a servers fixture instance and stores the collection
|
||||
export const createServersFixture = () => {
|
||||
const store = { servers: [] } as { servers: ServerFixture[] };
|
||||
return {
|
||||
create: async () => {
|
||||
const server = await nextServer();
|
||||
const serverFixture = createServerFixture(server);
|
||||
store.servers.push(serverFixture);
|
||||
return serverFixture;
|
||||
},
|
||||
get: () => store.servers,
|
||||
deleteAll: async () => {
|
||||
store.servers.forEach((server) => server.delete());
|
||||
store.servers = [];
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// creates the single server fixture
|
||||
const createServerFixture = (server: Server) => {
|
||||
const store = { server };
|
||||
|
||||
return {
|
||||
self: async () => store.server,
|
||||
delete: async () => store.server.close(),
|
||||
};
|
||||
};
|
|
@ -71,7 +71,7 @@ export const createUsersFixture = (page: Page, workerInfo: WorkerInfo) => {
|
|||
},
|
||||
get: () => store.users,
|
||||
logout: async () => {
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/auth/logout`);
|
||||
await page.goto("/auth/logout");
|
||||
},
|
||||
deleteAll: async () => {
|
||||
const ids = store.users.map((u) => u.id);
|
||||
|
@ -166,8 +166,7 @@ export async function login(
|
|||
const signInLocator = loginLocator.locator('[type="submit"]');
|
||||
|
||||
//login
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await page.goto(process.env.PLAYWRIGHT_TEST_BASE_URL!);
|
||||
await page.goto("/");
|
||||
await emailLocator.fill(user.email ?? `${user.username}@example.com`);
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
await passwordLocator.fill(user.password ?? user.username!);
|
||||
|
|
|
@ -4,14 +4,9 @@ import { setupServer } from "msw/node";
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import {
|
||||
createHttpServer,
|
||||
selectFirstAvailableTimeSlotNextMonth,
|
||||
todo,
|
||||
waitFor,
|
||||
} from "@calcom/web/playwright/lib/testUtils";
|
||||
|
||||
import { test } from "../lib/fixtures";
|
||||
import { test } from "./lib/fixtures";
|
||||
import { createHttpServer, selectFirstAvailableTimeSlotNextMonth, todo, waitFor } from "./lib/testUtils";
|
||||
|
||||
declare let global: {
|
||||
E2E_EMAILS?: ({ text: string } | Record<string, unknown>)[];
|
||||
|
@ -23,11 +18,6 @@ const requestInterceptor = setupServer(
|
|||
return res(ctx.status(200));
|
||||
})
|
||||
);
|
||||
requestInterceptor.listen({
|
||||
// Comment this to log which all requests are going that are unmocked
|
||||
onUnhandledRequest: "bypass",
|
||||
});
|
||||
requestInterceptor.use();
|
||||
|
||||
const addOauthBasedIntegration = async function ({
|
||||
page,
|
||||
|
@ -76,7 +66,7 @@ const addOauthBasedIntegration = async function ({
|
|||
})
|
||||
);
|
||||
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/apps/${slug}`);
|
||||
await page.goto(`/apps/${slug}`);
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
};
|
||||
|
||||
|
@ -113,7 +103,7 @@ async function bookEvent(page: Page, calLink: string) {
|
|||
// It would also allow correct snapshot to be taken for current month.
|
||||
// eslint-disable-next-line playwright/no-wait-for-timeout
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/${calLink}`);
|
||||
await page.goto(`/${calLink}`);
|
||||
|
||||
await page.locator('[data-testid="day"][data-disabled="false"]').nth(0).click();
|
||||
page.locator('[data-testid="time"]').nth(0).click();
|
||||
|
@ -155,7 +145,22 @@ async function bookEvent(page: Page, calLink: string) {
|
|||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Integrations", () => {
|
||||
// Enable API mocking before tests.
|
||||
test.beforeAll(() =>
|
||||
requestInterceptor.listen({
|
||||
// Comment this to log which all requests are going that are unmocked
|
||||
onUnhandledRequest: "bypass",
|
||||
})
|
||||
);
|
||||
|
||||
// Reset any runtime request handlers we may add during the tests.
|
||||
test.afterEach(() => requestInterceptor.resetHandlers());
|
||||
|
||||
// Disable API mocking after the tests are done.
|
||||
test.afterAll(() => requestInterceptor.close());
|
||||
|
||||
// TODO: Fix MSW mocking
|
||||
test.fixme("Integrations", () => {
|
||||
test.beforeEach(() => {
|
||||
global.E2E_EMAILS = [];
|
||||
});
|
||||
|
@ -365,7 +370,7 @@ test.describe("Integrations", () => {
|
|||
const user = await users.create();
|
||||
const [eventType] = user.eventTypes;
|
||||
await user.login();
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/settings/developer`);
|
||||
await page.goto(`/settings/developer`);
|
||||
|
||||
// --- add webhook
|
||||
await page.click('[data-testid="new_webhook"]');
|
||||
|
@ -384,7 +389,7 @@ test.describe("Integrations", () => {
|
|||
expect(page.locator(`text='${webhookReceiver.url}'`)).toBeDefined();
|
||||
|
||||
// --- Book the first available day next month in the pro user's "30min"-event
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/${user.username}/${eventType.slug}`);
|
||||
await page.goto(`/${user.username}/${eventType.slug}`);
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
// --- fill form
|
|
@ -1,13 +1,21 @@
|
|||
import { test as base } from "@playwright/test";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { createBookingsFixture } from "../fixtures/bookings";
|
||||
import { createEmbedsFixture, createGetActionFiredDetails } from "../fixtures/embeds";
|
||||
import { createPaymentsFixture } from "../fixtures/payments";
|
||||
import { createServersFixture } from "../fixtures/servers";
|
||||
import { createUsersFixture } from "../fixtures/users";
|
||||
|
||||
interface Fixtures {
|
||||
users: ReturnType<typeof createUsersFixture>;
|
||||
bookings: ReturnType<typeof createBookingsFixture>;
|
||||
payments: ReturnType<typeof createPaymentsFixture>;
|
||||
addEmbedListeners: ReturnType<typeof createEmbedsFixture>;
|
||||
getActionFiredDetails: ReturnType<typeof createGetActionFiredDetails>;
|
||||
servers: ReturnType<typeof createServersFixture>;
|
||||
prisma: typeof prisma;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,4 +34,19 @@ export const test = base.extend<Fixtures>({
|
|||
const payemntsFixture = createPaymentsFixture(page);
|
||||
await use(payemntsFixture);
|
||||
},
|
||||
addEmbedListeners: async ({ page }, use) => {
|
||||
const embedsFixture = createEmbedsFixture(page);
|
||||
await use(embedsFixture);
|
||||
},
|
||||
getActionFiredDetails: async ({ page }, use) => {
|
||||
const getActionFiredDetailsFixture = createGetActionFiredDetails(page);
|
||||
await use(getActionFiredDetailsFixture);
|
||||
},
|
||||
servers: async ({}, use) => {
|
||||
const servers = createServersFixture();
|
||||
await use(servers);
|
||||
},
|
||||
prisma: async ({}, use) => {
|
||||
await use(prisma);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ test("Should display Google Login button", async ({ page }) => {
|
|||
// eslint-disable-next-line playwright/no-skipped-test
|
||||
test.skip(!IS_GOOGLE_LOGIN_ENABLED, "It should only run if Google Login is installed");
|
||||
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/auth/login`);
|
||||
await page.goto(`/auth/login`);
|
||||
|
||||
await expect(page.locator(`[data-testid=google]`)).toBeVisible();
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ test("Should display SAML Login button", async ({ page }) => {
|
|||
// eslint-disable-next-line playwright/no-skipped-test
|
||||
test.skip(!IS_SAML_LOGIN_ENABLED, "It should only run if SAML Login is installed");
|
||||
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/auth/login`);
|
||||
await page.goto(`/auth/login`);
|
||||
|
||||
await expect(page.locator(`[data-testid=saml]`)).toBeVisible();
|
||||
});
|
|
@ -1,23 +1,15 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
test.describe("Onboarding", () => {
|
||||
test.use({ storageState: "playwright/artifacts/onboardingStorageState.json" });
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
// You want to always reset account completedOnboarding after each test
|
||||
test.afterEach(async () => {
|
||||
// Revert DB change
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
email: "onboarding@example.com",
|
||||
},
|
||||
data: {
|
||||
username: "onboarding",
|
||||
completedOnboarding: false,
|
||||
},
|
||||
});
|
||||
test.describe("Onboarding", () => {
|
||||
test.beforeEach(async ({ users }) => {
|
||||
const onboardingUser = await users.create({ completedOnboarding: false });
|
||||
await onboardingUser.login();
|
||||
});
|
||||
test.afterEach(({ users }) => users.deleteAll());
|
||||
|
||||
test("redirects to /getting-started after login", async ({ page }) => {
|
||||
await page.goto("/event-types");
|
||||
|
@ -29,10 +21,13 @@ test.describe("Onboarding", () => {
|
|||
});
|
||||
|
||||
test.describe("Onboarding", () => {
|
||||
test("update onboarding username via localstorage", async ({ page }) => {
|
||||
test("update onboarding username via localstorage", async ({ page, users }) => {
|
||||
const [onboardingUser] = users.get();
|
||||
/**
|
||||
* TODO:
|
||||
* We need to come up with a better test since all test are run in an incognito window.
|
||||
* Meaning that all localstorage access is null here.
|
||||
* Let's try saving the desiredUsername in the metadata instead
|
||||
*/
|
||||
test.fixme();
|
||||
await page.addInitScript(() => {
|
||||
|
@ -46,7 +41,7 @@ test.describe("Onboarding", () => {
|
|||
await page.waitForTimeout(1000);
|
||||
|
||||
const updatedUser = await prisma.user.findUnique({
|
||||
where: { email: "onboarding@example.com" },
|
||||
where: { id: onboardingUser.id },
|
||||
select: { id: true, username: true },
|
||||
});
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { test } from "@playwright/test";
|
||||
|
||||
import { IS_SAML_LOGIN_ENABLED } from "../server/lib/constants";
|
||||
import { login } from "./fixtures/users";
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.describe("SAML tests", () => {
|
||||
// Using logged in state from globalSteup
|
||||
test.use({ storageState: "playwright/artifacts/proStorageState.json" });
|
||||
|
||||
test("test SAML configuration UI with pro@example.com", async ({ page }) => {
|
||||
// TODO: Figure out a way to use the users from fixtures here, right now we cannot set
|
||||
// the SAML_ADMINS env variables dynamically
|
||||
await login({ username: "pro", email: "pro@example.com", password: "pro" }, page);
|
||||
// eslint-disable-next-line playwright/no-skipped-test
|
||||
test.skip(!IS_SAML_LOGIN_ENABLED, "It should only run if SAML is enabled");
|
||||
// Try to go Security page
|
|
@ -50,6 +50,22 @@ const config: Config = {
|
|||
testEnvironment: "jsdom",
|
||||
setupFiles: ["<rootDir>/packages/app-store/closecomothercalendar/test/globals.ts"],
|
||||
},
|
||||
{
|
||||
displayName: "@calcom/api",
|
||||
roots: ["<rootDir>/apps/api"],
|
||||
testMatch: ["**/test/lib/**/*.(spec|test).(ts|tsx|js)"],
|
||||
transform: {
|
||||
"^.+\\.ts?$": "ts-jest",
|
||||
},
|
||||
transformIgnorePatterns: ["/node_modules/", "^.+\\.module\\.(css|sass|scss)$"],
|
||||
testEnvironment: "node",
|
||||
clearMocks: true,
|
||||
moduleNameMapper: {
|
||||
"^@lib/(.*)$": "<rootDir>/apps/api/lib/$1",
|
||||
"^@api/(.*)$": "<rootDir>/apps/api/pages/api/$1",
|
||||
},
|
||||
// setupFilesAfterEnv: ["<rootDir>/apps/api/jest.setup.ts"], // Uncomment when API becomes public
|
||||
},
|
||||
],
|
||||
watchPlugins: [
|
||||
"jest-watch-typeahead/filename",
|
||||
|
|
10
package.json
10
package.json
|
@ -11,12 +11,11 @@
|
|||
"packages/app-store/ee/*"
|
||||
],
|
||||
"scripts": {
|
||||
"app-e2e-quick": "turbo run app-e2e-quick",
|
||||
"app-store-cli": "yarn workspace @calcom/app-store-cli",
|
||||
"app-store:build": "yarn app-store-cli build",
|
||||
"app-store:watch": "yarn app-store-cli watch",
|
||||
"app-store": "yarn app-store-cli cli",
|
||||
"build": "turbo run build --scope=\"@calcom/web\" --include-dependencies",
|
||||
"build": "turbo run build --filter=@calcom/web...",
|
||||
"clean": "find . -name node_modules -o -name .next -o -name .turbo -o -name dist -type d -prune | xargs rm -rf",
|
||||
"db-deploy": "turbo run db-deploy",
|
||||
"db-seed": "turbo run db-seed",
|
||||
|
@ -49,12 +48,13 @@
|
|||
"prisma": "yarn workspace @calcom/prisma prisma",
|
||||
"start": "turbo run start --scope=\"@calcom/web\"",
|
||||
"tdd": "jest --watch",
|
||||
"test-e2e": "turbo run test --scope=\"@calcom/web\" && yarn turbo run test-e2e --scope=\"@calcom/web\" --concurrency=1",
|
||||
"e2e": "NEXT_PUBLIC_IS_E2E=1 yarn playwright test --project=@calcom/web",
|
||||
"e2e:app-store": "QUICK=true yarn playwright test --project=@calcom/app-store",
|
||||
"test-e2e": "yarn db-seed && yarn build && yarn e2e",
|
||||
"test-e2e:app-store": "yarn db-seed && yarn build && yarn e2e:app-store",
|
||||
"test-playwright": "yarn playwright test --config=tests/config/playwright.config.ts",
|
||||
"test": "jest",
|
||||
"turbo-w": "node turbo-wrapper.js",
|
||||
"type-check": "turbo run type-check",
|
||||
"test-e2e-integrations": "turbo run test-e2e-integrations --scope=\"@calcom/web\" --concurrency=1",
|
||||
"web": "yarn workspace @calcom/web"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import { Page } from "@playwright/test";
|
||||
|
||||
export async function loginAsUser(username: string, page: Page) {
|
||||
// Skip if file exists
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/auth/login`);
|
||||
// Click input[name="email"]
|
||||
await page.click('input[name="email"]');
|
||||
// Fill input[name="email"]
|
||||
await page.fill('input[name="email"]', `${username}@example.com`);
|
||||
// Press Tab
|
||||
await page.press('input[name="email"]', "Tab");
|
||||
// Fill input[name="password"]
|
||||
await page.fill('input[name="password"]', username);
|
||||
// Press Enter
|
||||
await page.press('input[name="password"]', "Enter");
|
||||
await page.waitForSelector("[data-testid=dashboard-shell]");
|
||||
// Save signed-in state to '${username}StorageState.json'.
|
||||
await page.context().storageState({ path: `playwright/artifacts/${username}StorageState.json` });
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { PlaywrightTestConfig, devices } from "@playwright/test";
|
||||
import { config as dotEnvConfig } from "dotenv";
|
||||
import * as path from "path";
|
||||
|
||||
// TODO: May be derive it automatically, so that moving the file to another location doesn't require changing the code
|
||||
dotEnvConfig({ path: "../../../../../.env" });
|
||||
const DEFAULT_NAVIGATION_TIMEOUT = 15000;
|
||||
|
||||
// Paths are relative to main playwright config.
|
||||
const outputDir = path.join("../results");
|
||||
const testDir = path.join("../tests");
|
||||
|
||||
// Quick Mode has no retries to fail fast and quickly re-iterate
|
||||
// Also, it runs the tests only one browser for the same reason
|
||||
const quickMode = process.env.QUICK === "true";
|
||||
const CI = process.env.CI;
|
||||
export const config: PlaywrightTestConfig = {
|
||||
forbidOnly: !!CI,
|
||||
retries: quickMode && !CI ? 0 : 1,
|
||||
workers: 1,
|
||||
timeout: 60_000,
|
||||
reporter: [
|
||||
[CI ? "github" : "list"],
|
||||
[
|
||||
"html",
|
||||
{
|
||||
outputFolder: path.join(process.cwd(), "playwright", "reports", "playwright-html-report"),
|
||||
open: "never",
|
||||
},
|
||||
],
|
||||
["junit", { outputFile: path.join(process.cwd(), "playwright", "reports", "results.xml") }],
|
||||
],
|
||||
outputDir,
|
||||
webServer: {
|
||||
command: "NEXT_PUBLIC_IS_E2E=1 yarn workspace @calcom/web start -p 3000",
|
||||
port: 3000,
|
||||
timeout: 60_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
use: {
|
||||
baseURL: "http://localhost:3000",
|
||||
locale: "en-US",
|
||||
trace: "retain-on-failure",
|
||||
headless: !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
testDir,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
/** If navigation takes more than this, then something's wrong, let's fail fast. */
|
||||
navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
export * from "../../../../apps/web/playwright/lib/testUtils";
|
|
@ -5,7 +5,7 @@ import {
|
|||
getCloseComCustomActivityTypeFieldsIds,
|
||||
getCloseComLeadId,
|
||||
} from "@calcom/lib/CloseComeUtils";
|
||||
import { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
jest.mock("@calcom/lib/CloseCom", () => ({
|
||||
default: class {
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
"version": "0.0.0",
|
||||
"main": "./index.ts",
|
||||
"description": "It would allow a booker to connect with the right person or choose the right event, faster. It would work by taking inputs from the booker and using that data to route to the correct booker/event as configured by Cal user ",
|
||||
"scripts": {
|
||||
"app-e2e": "yarn playwright test --config=playwright/config/playwright.config.ts",
|
||||
"app-e2e-quick": "QUICK=true yarn app-e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"@calcom/lib": "*",
|
||||
"dotenv": "^16.0.1",
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
import { Page, chromium } from "@playwright/test";
|
||||
|
||||
// TODO: Import it in _playwright/config/globalSetup.ts and export it from there.
|
||||
import { loginAsUser } from "@calcom/app-store/_apps-playwright/config/globalSetup";
|
||||
import { hashPassword } from "@calcom/lib/auth";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
async function installApp(appName: string, redirectUrl: string, page: Page) {
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/apps/${appName}`);
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
await page.waitForNavigation({
|
||||
url: (url) => {
|
||||
return url.pathname == redirectUrl;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function createUser(userName: string) {
|
||||
const email = `${userName}@example.com`;
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
username: userName,
|
||||
email,
|
||||
completedOnboarding: true,
|
||||
password: await hashPassword(userName),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function globalSetup(/* config: FullConfig */) {
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
const appName = "routing_forms";
|
||||
const userName = `${appName}-e2e-${Math.random()}`;
|
||||
process.env.APP_USER_NAME = userName;
|
||||
await createUser(userName);
|
||||
await loginAsUser(userName, page);
|
||||
await installApp(appName, `/apps/${appName}/forms`, page);
|
||||
page.context().close();
|
||||
}
|
||||
|
||||
export default globalSetup;
|
|
@ -1,18 +0,0 @@
|
|||
import prisma from "@calcom/prisma";
|
||||
|
||||
async function deleteUser(userName: string) {
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
AND: {
|
||||
username: {
|
||||
contains: userName,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
async function globalTeardown(/* config: FullConfig */) {
|
||||
await deleteUser("routing_forms-e2e");
|
||||
}
|
||||
|
||||
export default globalTeardown;
|
|
@ -1,12 +0,0 @@
|
|||
import { expect, Config } from "@playwright/test";
|
||||
|
||||
import { config as baseConfig } from "@calcom/app-store/_apps-playwright/config/playwright.config";
|
||||
|
||||
const config: Config = {
|
||||
...baseConfig,
|
||||
globalSetup: require.resolve("./globalSetup"),
|
||||
globalTeardown: require.resolve("./globalTeardown"),
|
||||
};
|
||||
|
||||
expect.extend({});
|
||||
export default config;
|
|
@ -1,5 +0,0 @@
|
|||
import { test as base } from "@playwright/test";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
interface Fixtures {}
|
||||
export const test = base.extend<Fixtures>({});
|
|
@ -1,20 +0,0 @@
|
|||
import prisma from "@calcom/prisma";
|
||||
|
||||
export * from "@calcom/app-store/_apps-playwright/lib/testUtils";
|
||||
export async function cleanUpForms() {
|
||||
await prisma.app_RoutingForms_Form.deleteMany({
|
||||
where: {
|
||||
user: {
|
||||
username: process.env.APP_USER_NAME,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function cleanUpSeededForm(formId: string) {
|
||||
return await prisma.app_RoutingForms_FormResponse.deleteMany({
|
||||
where: {
|
||||
formId,
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
import { expect, Page } from "@playwright/test";
|
||||
|
||||
import { seededForm } from "@calcom/prisma/seed-app-store";
|
||||
|
||||
import { test } from "../fixtures/fixtures";
|
||||
import { cleanUpForms, cleanUpSeededForm } from "../lib/testUtils";
|
||||
import { test } from "@calcom/web/playwright/lib/fixtures";
|
||||
|
||||
async function gotoRoutingLink(page: Page, formId: string) {
|
||||
await page.goto(`/forms/${formId}`);
|
||||
|
@ -69,12 +67,24 @@ async function fillForm(
|
|||
};
|
||||
}
|
||||
|
||||
test.use({ storageState: `playwright/artifacts/${process.env.APP_USER_NAME}StorageState.json` });
|
||||
test.describe("Routing Forms", () => {
|
||||
test("should be able to add a new form and view it", async ({ page }) => {
|
||||
page.goto("/");
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const user = await users.create({ username: "routing_forms" });
|
||||
await user.login();
|
||||
// Install app
|
||||
await page.goto(`/apps/routing_forms`);
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
await page.waitForNavigation({
|
||||
url: (url) => url.pathname === `/apps/routing_forms/forms`,
|
||||
});
|
||||
});
|
||||
|
||||
await page.click('[href="/apps/routing_forms/forms"]');
|
||||
test.afterEach(async ({ users }) => {
|
||||
// This also delete forms on cascade
|
||||
await users.deleteAll();
|
||||
});
|
||||
|
||||
test("should be able to add a new form and view it", async ({ page }) => {
|
||||
await page.waitForSelector('[data-testid="empty-screen"]');
|
||||
|
||||
const formId = await addForm(page);
|
||||
|
@ -98,8 +108,6 @@ test.describe("Routing Forms", () => {
|
|||
});
|
||||
|
||||
test("should be able to edit the form", async ({ page }) => {
|
||||
await page.goto("/apps/routing_forms/forms");
|
||||
|
||||
await addForm(page);
|
||||
const description = "Test Description";
|
||||
|
||||
|
@ -218,12 +226,4 @@ test.describe("Routing Forms", () => {
|
|||
expect(await page.locator('button[type="submit"][disabled]').count()).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
test.afterAll(() => {
|
||||
cleanUpForms();
|
||||
});
|
||||
|
||||
test.afterEach(() => {
|
||||
cleanUpSeededForm(seededForm.id);
|
||||
});
|
||||
});
|
|
@ -1,7 +1,8 @@
|
|||
import { expect, Frame } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import { test } from "../fixtures/fixtures";
|
||||
import { todo, getEmbedIframe, bookFirstEvent, deleteAllBookingsByEmail } from "../lib/testUtils";
|
||||
import { test } from "@calcom/web/playwright/lib/fixtures";
|
||||
|
||||
import { bookFirstEvent, deleteAllBookingsByEmail, getEmbedIframe, todo } from "../lib/testUtils";
|
||||
|
||||
test("Inline Iframe - Configured with Dark Theme", async ({
|
||||
page,
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "@playwright/test";
|
||||
|
||||
import { test } from "../fixtures/fixtures";
|
||||
import { test } from "@calcom/web/playwright/lib/fixtures";
|
||||
|
||||
test("Preview - embed-core should load", async ({ page }) => {
|
||||
await page.goto("http://localhost:3000/embed/preview.html");
|
|
@ -1,4 +1,4 @@
|
|||
import { CalendarEvent } from "@calcom/types/Calendar";
|
||||
import type { CalendarEvent } from "@calcom/types/Calendar";
|
||||
|
||||
import CloseCom, {
|
||||
CloseComCustomActivityCreate,
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import { devices, PlaywrightTestConfig } from "@playwright/test";
|
||||
import dotEnv from "dotenv";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
|
||||
dotEnv.config({ path: ".env" });
|
||||
|
||||
const outputDir = path.join(__dirname, "test-results");
|
||||
const testDir = path.join(__dirname, "apps/web/playwright");
|
||||
|
||||
const DEFAULT_NAVIGATION_TIMEOUT = 15000;
|
||||
|
||||
const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS;
|
||||
|
||||
const IS_EMBED_TEST = process.argv.some((a) => a.startsWith("--project=@calcom/embed-core"));
|
||||
|
||||
const webServer: PlaywrightTestConfig["webServer"] = [
|
||||
{
|
||||
command: "NEXT_PUBLIC_IS_E2E=1 yarn workspace @calcom/web start -p 3000",
|
||||
port: 3000,
|
||||
timeout: 60_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
];
|
||||
|
||||
if (IS_EMBED_TEST) {
|
||||
webServer.push({
|
||||
command: "yarn workspace @calcom/embed-core run-p 'embed-dev' 'embed-web-start'",
|
||||
port: 3100,
|
||||
timeout: 60_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
});
|
||||
}
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: 1,
|
||||
workers: os.cpus().length,
|
||||
timeout: 60_000,
|
||||
maxFailures: headless ? 10 : undefined,
|
||||
reporter: [
|
||||
[process.env.CI ? "github" : "list"],
|
||||
["html", { outputFolder: "./test-results/reports/playwright-html-report", open: "never" }],
|
||||
["junit", { outputFile: "./test-results/reports/results.xml" }],
|
||||
],
|
||||
outputDir: path.join(outputDir, "results"),
|
||||
webServer,
|
||||
use: {
|
||||
baseURL: "http://localhost:3000/",
|
||||
locale: "en-US",
|
||||
trace: "retain-on-failure",
|
||||
headless,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: "@calcom/web",
|
||||
testDir: "./apps/web/playwright",
|
||||
testMatch: /.*\.e2e\.tsx?/,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
/** If navigation takes more than this, then something's wrong, let's fail fast. */
|
||||
navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "@calcom/app-store",
|
||||
testDir: "./packages/app-store/",
|
||||
testMatch: /.*\.e2e\.tsx?/,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
/** If navigation takes more than this, then something's wrong, let's fail fast. */
|
||||
navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "@calcom/embed-core",
|
||||
testDir: "./packages/embeds/",
|
||||
testMatch: /.*\.e2e\.tsx?/,
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
{
|
||||
name: "@calcom/embed-core--firefox",
|
||||
testDir: "./packages/embeds/",
|
||||
testMatch: /.*\.e2e\.tsx?/,
|
||||
use: { ...devices["Desktop Firefox"] },
|
||||
},
|
||||
{
|
||||
name: "@calcom/embed-core--webkit",
|
||||
testDir: "./packages/embeds/",
|
||||
testMatch: /.*\.e2e\.tsx?/,
|
||||
use: { ...devices["Desktop Safari"] },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -1,48 +0,0 @@
|
|||
import { loadEnvConfig } from "@next/env";
|
||||
import { Browser, chromium } from "@playwright/test";
|
||||
import fs from "fs";
|
||||
|
||||
export async function loginAsUser(username: string, browser: Browser) {
|
||||
// Skip is file exists
|
||||
if (fs.existsSync(`playwright/artifacts/${username}StorageState.json`)) return;
|
||||
const page = await browser.newPage();
|
||||
await page.goto(`${process.env.PLAYWRIGHT_TEST_BASE_URL}/auth/login`);
|
||||
// Click input[name="email"]
|
||||
await page.click('input[name="email"]');
|
||||
// Fill input[name="email"]
|
||||
await page.fill('input[name="email"]', `${username}@example.com`);
|
||||
// Press Tab
|
||||
await page.press('input[name="email"]', "Tab");
|
||||
// Fill input[name="password"]
|
||||
await page.fill('input[name="password"]', username);
|
||||
// Press Enter
|
||||
await page.press('input[name="password"]', "Enter");
|
||||
await page.waitForSelector(
|
||||
username === "onboarding" ? "[data-testid=onboarding]" : "[data-testid=dashboard-shell]"
|
||||
);
|
||||
// Save signed-in state to '${username}StorageState.json'.
|
||||
await page.context().storageState({ path: `playwright/artifacts/${username}StorageState.json` });
|
||||
await page.context().close();
|
||||
}
|
||||
|
||||
async function globalSetup(/* config: FullConfig */) {
|
||||
loadEnvConfig(process.env.PWD);
|
||||
const browser = await chromium.launch();
|
||||
|
||||
await loginAsUser("onboarding", browser);
|
||||
// await loginAsUser("free-first-hidden", browser);
|
||||
await loginAsUser("pro", browser);
|
||||
await loginAsUser("trial", browser);
|
||||
await loginAsUser("free", browser);
|
||||
// await loginAsUser("usa", browser);
|
||||
// await loginAsUser("teamfree", browser);
|
||||
await loginAsUser("teampro", browser);
|
||||
await browser.close();
|
||||
// Clean up auth state after all tests are done
|
||||
return () => {
|
||||
const dir = `playwright/artifacts`;
|
||||
fs.readdirSync(dir).forEach((f) => fs.rmSync(`${dir}/${f}`));
|
||||
};
|
||||
}
|
||||
|
||||
export default globalSetup;
|
|
@ -1,61 +0,0 @@
|
|||
import { devices, PlaywrightTestConfig } from "@playwright/test";
|
||||
import dotEnv from "dotenv";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
|
||||
dotEnv.config({ path: "../../.env" });
|
||||
|
||||
const outputDir = path.join(__dirname, "..", "..", "test-results");
|
||||
const testDir = path.join(__dirname, "..", "..", "apps/web/playwright");
|
||||
|
||||
const DEFAULT_NAVIGATION_TIMEOUT = 15000;
|
||||
|
||||
const headless = !!process.env.CI || !!process.env.PLAYWRIGHT_HEADLESS;
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: 1,
|
||||
workers: os.cpus().length,
|
||||
timeout: 60_000,
|
||||
maxFailures: headless ? 10 : undefined,
|
||||
reporter: [
|
||||
[process.env.CI ? "github" : "list"],
|
||||
["html", { outputFolder: path.join(outputDir, "reports/playwright-html-report"), open: "never" }],
|
||||
["junit", { outputFile: path.join(outputDir, "reports/results.xml") }],
|
||||
],
|
||||
globalSetup: require.resolve("./globalSetup"),
|
||||
outputDir: path.join(outputDir, "results"),
|
||||
webServer: {
|
||||
command: "NEXT_PUBLIC_IS_E2E=1 yarn workspace @calcom/web start -p 3000",
|
||||
port: 3000,
|
||||
timeout: 60_000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
use: {
|
||||
baseURL: "http://localhost:3000/",
|
||||
locale: "en-US",
|
||||
trace: "retain-on-failure",
|
||||
headless,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
testDir,
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
/** If navigation takes more than this, then something's wrong, let's fail fast. */
|
||||
navigationTimeout: DEFAULT_NAVIGATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
/* {
|
||||
name: "firefox",
|
||||
use: { ...devices["Desktop Firefox"] },
|
||||
},
|
||||
{
|
||||
name: "webkit",
|
||||
use: { ...devices["Desktop Safari"] },
|
||||
}, */
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
27
turbo.json
27
turbo.json
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"$schema": "https://turborepo.org/schema.json",
|
||||
"baseBranch": "origin/main",
|
||||
"pipeline": {
|
||||
"@calcom/prisma#build": {
|
||||
"cache": false,
|
||||
|
@ -123,24 +122,6 @@
|
|||
"embed-tests-quick": {
|
||||
"cache": false
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": ["^test"]
|
||||
},
|
||||
"@calcom/web#db-setup-tests": {
|
||||
"cache": false
|
||||
},
|
||||
"@calcom/web#test": {
|
||||
"cache": false,
|
||||
"dependsOn": ["@calcom/web#db-setup-tests"]
|
||||
},
|
||||
"test-e2e": {
|
||||
"cache": false,
|
||||
"dependsOn": ["@calcom/prisma#db-seed", "@calcom/web#build"]
|
||||
},
|
||||
"test-e2e-integrations": {
|
||||
"cache": false,
|
||||
"dependsOn": ["@calcom/prisma#db-seed", "@calcom/web#build"]
|
||||
},
|
||||
"type-check": {
|
||||
"cache": false,
|
||||
"outputs": []
|
||||
|
@ -170,10 +151,6 @@
|
|||
"^embed-tests-update-snapshots:ci"
|
||||
]
|
||||
},
|
||||
"app-e2e-quick": {
|
||||
"cache": false,
|
||||
"dependsOn": ["@calcom/prisma#db-seed", "@calcom/web#build", "^app-e2e-quick"]
|
||||
},
|
||||
"//#env-check:common": {
|
||||
"cache": false,
|
||||
"inputs": ["./.env.example", "./.env"],
|
||||
|
@ -183,6 +160,10 @@
|
|||
"cache": false,
|
||||
"inputs": ["./.env.appStore.example", "./.env.appStore"],
|
||||
"outputs": ["./.env.appStore"]
|
||||
},
|
||||
"//#test": {
|
||||
"cache": false,
|
||||
"outputs": []
|
||||
}
|
||||
},
|
||||
"globalDependencies": [
|
||||
|
|
266
yarn.lock
266
yarn.lock
|
@ -2410,17 +2410,12 @@
|
|||
resolved "https://registry.yarnpkg.com/@glidejs/glide/-/glide-3.5.2.tgz#7012c5920ecf202bbda44d8526fc979984b6dd54"
|
||||
integrity sha512-7jGciNJ2bQ4eZLSNlSZ+VAyW63kALf420CvkEpK4lEsUfWJq9odqimci0YCiyNyMUFB+pWHwLYyNc57dijYsCg==
|
||||
|
||||
"@headlessui/react@^1.4.1":
|
||||
version "1.6.6"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.6.tgz#3073c066b85535c9d28783da0a4d9288b5354d0c"
|
||||
integrity sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==
|
||||
|
||||
"@headlessui/react@^1.5.0":
|
||||
version "1.6.5"
|
||||
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.5.tgz#5587c537de809cf3146eb2ff263e5e940b1bf69c"
|
||||
integrity sha512-3VkKteDxlxf3fE0KbfO9t60KC1lM7YNpZggLpwzVNg1J/zwL+h+4N7MBlFDVpInZI3rKlZGpNx0PWsG/9c2vQg==
|
||||
|
||||
"@heroicons/react@^1.0.4", "@heroicons/react@^1.0.6":
|
||||
"@heroicons/react@^1.0.6":
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324"
|
||||
integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==
|
||||
|
@ -3770,17 +3765,6 @@
|
|||
"@radix-ui/react-primitive" "0.1.4"
|
||||
"@radix-ui/react-slot" "0.1.2"
|
||||
|
||||
"@radix-ui/react-collection@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.0.tgz#0ec4c72fabd35a03b5787075ac799e3b17ca5710"
|
||||
integrity sha512-8i1pf5dKjnq90Z8udnnXKzdCEV3/FYrfw0n/b6NvB6piXEn3fO1bOh7HBcpG8XrnIXzxlYu2oCcR38QpyLS/mg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-compose-refs" "1.0.0"
|
||||
"@radix-ui/react-context" "1.0.0"
|
||||
"@radix-ui/react-primitive" "1.0.0"
|
||||
"@radix-ui/react-slot" "1.0.0"
|
||||
|
||||
"@radix-ui/react-compose-refs@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
|
||||
|
@ -3830,13 +3814,6 @@
|
|||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "^2.4.0"
|
||||
|
||||
"@radix-ui/react-direction@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.0.tgz#a2e0b552352459ecf96342c79949dd833c1e6e45"
|
||||
integrity sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@radix-ui/react-dismissable-layer@0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.5.tgz#9379032351e79028d472733a5cc8ba4a0ea43314"
|
||||
|
@ -3984,7 +3961,7 @@
|
|||
"@radix-ui/react-primitive" "0.1.4"
|
||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||
|
||||
"@radix-ui/react-portal@1.0.0", "@radix-ui/react-portal@^1.0.0":
|
||||
"@radix-ui/react-portal@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.0.tgz#7220b66743394fabb50c55cb32381395cc4a276b"
|
||||
integrity sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==
|
||||
|
@ -4058,22 +4035,6 @@
|
|||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||
|
||||
"@radix-ui/react-roving-focus@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.0.tgz#aadeb65d5dbcdbdd037078156ae1f57c2ff754ee"
|
||||
integrity sha512-lHvO4MhvoWpeNbiJAoyDsEtbKqP2jkkdwsMVJ3kfqbkC71J/aXE6Th6gkZA1xHEqSku+t+UgoDjvE7Z3gsBpcg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.0"
|
||||
"@radix-ui/react-collection" "1.0.0"
|
||||
"@radix-ui/react-compose-refs" "1.0.0"
|
||||
"@radix-ui/react-context" "1.0.0"
|
||||
"@radix-ui/react-direction" "1.0.0"
|
||||
"@radix-ui/react-id" "1.0.0"
|
||||
"@radix-ui/react-primitive" "1.0.0"
|
||||
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||
|
||||
"@radix-ui/react-select@^0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-0.1.1.tgz#ceedea6856a37e4079492e1c69601797cedd2c85"
|
||||
|
@ -4099,7 +4060,7 @@
|
|||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "^2.4.0"
|
||||
|
||||
"@radix-ui/react-slider@^0.1.0", "@radix-ui/react-slider@^0.1.1":
|
||||
"@radix-ui/react-slider@^0.1.1":
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-0.1.4.tgz#a7b7a480ee00158195794b08cd3f1583cf102518"
|
||||
integrity sha512-0z3bCcdrAi+FIcoLXS6r0ESVWuuyMnUJoCsFm7tC7Rtv95x34YtaI8YfSyQmzuMVS4rTsNtCCTZ/s727uRaVkQ==
|
||||
|
@ -4148,21 +4109,6 @@
|
|||
"@radix-ui/react-use-previous" "0.1.1"
|
||||
"@radix-ui/react-use-size" "0.1.1"
|
||||
|
||||
"@radix-ui/react-tabs@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.0.tgz#135c67f1f2bd9ada69a3f6e38dd897d459af5fe5"
|
||||
integrity sha512-oKUwEDsySVC0uuSEH7SHCVt1+ijmiDFAI9p+fHCtuZdqrRDKIFs09zp5nrmu4ggP6xqSx9lj1VSblnDH+n3IBA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/primitive" "1.0.0"
|
||||
"@radix-ui/react-context" "1.0.0"
|
||||
"@radix-ui/react-direction" "1.0.0"
|
||||
"@radix-ui/react-id" "1.0.0"
|
||||
"@radix-ui/react-presence" "1.0.0"
|
||||
"@radix-ui/react-primitive" "1.0.0"
|
||||
"@radix-ui/react-roving-focus" "1.0.0"
|
||||
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||
|
||||
"@radix-ui/react-toggle-group@^0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-0.1.5.tgz#9e4d65e22c4fc0ba3a42fbc8d5496c430e5e9852"
|
||||
|
@ -5746,7 +5692,7 @@
|
|||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@stripe/stripe-js@^1.17.1", "@stripe/stripe-js@^1.35.0":
|
||||
"@stripe/stripe-js@^1.34.0", "@stripe/stripe-js@^1.35.0":
|
||||
version "1.35.0"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.35.0.tgz#f809e2e5e0a00f01aa12e8aed0b89d27728c05c0"
|
||||
integrity sha512-UIuzpbJqgXCTvJhY/aZYvBtaKdMfQgnIv6kkLlfRJ9smZcC4zoPvq3j7k9wobYI+idHAWP4BRiPnqA8lvzJCtg==
|
||||
|
@ -6373,16 +6319,11 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@16.9.1", "@types/node@>=12.0.0", "@types/node@>=8.1.0", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0":
|
||||
"@types/node@*", "@types/node@16.9.1", "@types/node@>=12.0.0", "@types/node@>=8.1.0", "@types/node@^12.12.6", "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0":
|
||||
version "16.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708"
|
||||
integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==
|
||||
|
||||
"@types/node@^12.12.6":
|
||||
version "12.20.55"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
||||
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
|
||||
|
||||
"@types/nodemailer@^6.4.5":
|
||||
version "6.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.5.tgz#09011ac73259245475d1688e4ba101860567dc39"
|
||||
|
@ -6511,7 +6452,7 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@>=16", "@types/react@^18.0.17":
|
||||
"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@>=16", "@types/react@^18.0.17", "@types/react@^18.0.9":
|
||||
version "18.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.17.tgz#4583d9c322d67efe4b39a935d223edcc7050ccf4"
|
||||
integrity sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==
|
||||
|
@ -6520,24 +6461,6 @@
|
|||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@18.0.9":
|
||||
version "18.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878"
|
||||
integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@^18.0.9":
|
||||
version "18.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.18.tgz#9f16f33d57bc5d9dca848d12c3572110ff9429ac"
|
||||
integrity sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/responselike@*", "@types/responselike@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
|
||||
|
@ -7846,7 +7769,7 @@ autolinker@^3.11.0:
|
|||
dependencies:
|
||||
tslib "^2.3.0"
|
||||
|
||||
autoprefixer@^10.3.4, autoprefixer@^10.4.7, autoprefixer@^10.4.8:
|
||||
autoprefixer@^10.4.7, autoprefixer@^10.4.8:
|
||||
version "10.4.8"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.8.tgz#92c7a0199e1cfb2ad5d9427bd585a3d75895b9e5"
|
||||
integrity sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==
|
||||
|
@ -10220,11 +10143,6 @@ denque@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/denque/-/denque-2.0.1.tgz#bcef4c1b80dc32efe97515744f21a4229ab8934a"
|
||||
integrity sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==
|
||||
|
||||
depd@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
|
||||
integrity sha512-Jlk9xvkTDGXwZiIDyoM7+3AsuvJVoyOpRupvEVy9nX3YO3/ieZxhlgh8GpLNZ8AY7HjO6y2YwpMSh1ejhu3uIw==
|
||||
|
||||
depd@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
|
@ -11301,7 +11219,7 @@ eslint@8.4.1:
|
|||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
eslint@^8.15.0, eslint@^8.20.0:
|
||||
eslint@^8.20.0:
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
|
||||
integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
|
||||
|
@ -13072,11 +12990,6 @@ gray-matter@^4.0.3:
|
|||
section-matter "^1.0.0"
|
||||
strip-bom-string "^1.0.0"
|
||||
|
||||
gsap@^3.11.0:
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/gsap/-/gsap-3.11.0.tgz#5a45da0f35b49e2c479e1e274feb6ac51e86478b"
|
||||
integrity sha512-TV5aFGqXht+0o/CelnhCikSe3QGeG+q1XA/fyFFsMzesILHgWgFWIz0NuXIgcMaL5h7MG2l+j0BTupS5YyYkrw==
|
||||
|
||||
gtoken@^5.0.4:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.2.tgz#deb7dc876abe002178e0515e383382ea9446d58f"
|
||||
|
@ -13546,16 +13459,6 @@ http-cache-semantics@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
|
||||
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
|
||||
|
||||
http-errors@1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
|
||||
integrity sha512-STnYGcKMXL9CGdtpeTFnLmgMSHTTNQJSHxiC4DETHKf934Q160Ht5pljrNeH24S0O9xUN+9vsDJZdZtk5js6Ww==
|
||||
dependencies:
|
||||
depd "1.1.1"
|
||||
inherits "2.0.3"
|
||||
setprototypeof "1.0.3"
|
||||
statuses ">= 1.3.1 < 2"
|
||||
|
||||
http-errors@1.7.3:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
|
||||
|
@ -13684,11 +13587,6 @@ ical.js@^1.4.0:
|
|||
resolved "https://registry.yarnpkg.com/ical.js/-/ical.js-1.5.0.tgz#23213accd1d8f7248d01705acb06270a70d20662"
|
||||
integrity sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==
|
||||
|
||||
iconv-lite@0.4.19:
|
||||
version "0.4.19"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
|
||||
integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.13:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
|
@ -14439,7 +14337,7 @@ is-shared-array-buffer@^1.0.1, is-shared-array-buffer@^1.0.2:
|
|||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
|
||||
is-stream@1.1.0, is-stream@^1.0.0, is-stream@^1.1.0:
|
||||
is-stream@^1.0.0, is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
@ -16554,17 +16452,7 @@ methods@^1.1.2, methods@~1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
|
||||
micro@9.3.4:
|
||||
version "9.3.4"
|
||||
resolved "https://registry.yarnpkg.com/micro/-/micro-9.3.4.tgz#745a494e53c8916f64fb6a729f8cbf2a506b35ad"
|
||||
integrity sha512-smz9naZwTG7qaFnEZ2vn248YZq9XR+XoOH3auieZbkhDL4xLOxiE+KqG8qqnBeKfXA9c1uEFGCxPN1D+nT6N7w==
|
||||
dependencies:
|
||||
arg "4.1.0"
|
||||
content-type "1.0.4"
|
||||
is-stream "1.1.0"
|
||||
raw-body "2.3.2"
|
||||
|
||||
micro@^9.4.1:
|
||||
micro@^9.4.0, micro@^9.4.1:
|
||||
version "9.4.1"
|
||||
resolved "https://registry.yarnpkg.com/micro/-/micro-9.4.1.tgz#3a7eedd96718d8569a324475cd1967441df4b3c7"
|
||||
integrity sha512-Lpjcbp6Y9GJIfewxDfTmu9eW0rt0MGo+Gs1d3yJLFa7mhErtKkCngGhDbA/O1gqUjEwsHh+jWPg8BJ0Bx4AgFA==
|
||||
|
@ -17524,7 +17412,7 @@ next-validations@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/next-validations/-/next-validations-0.2.1.tgz#68010c9b017ba48eec4f404fd42eb9b0c7324737"
|
||||
integrity sha512-92pR14MPTTx0ynlvYH2TwMf7WiGiznNL/l0dtZyKPw3x48rcMhwEZrP1ZmsMJwzp5D+U+sY2deexeLWC8rlNtQ==
|
||||
|
||||
next@^12.2.0, next@^12.2.5:
|
||||
next@^12.2.5:
|
||||
version "12.2.5"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.2.5.tgz#14fb5975e8841fad09553b8ef41fe1393602b717"
|
||||
integrity sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA==
|
||||
|
@ -19478,16 +19366,6 @@ range-parser@^1.2.0, range-parser@^1.2.1, range-parser@~1.2.1:
|
|||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
raw-body@2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
|
||||
integrity sha512-Ss0DsBxqLxCmQkfG5yazYhtbVVTJqS9jTsZG2lhrNwqzOk2SUC7O/NB/M//CkEBqsrtmlNgJCPccJGuYSFr6Vg==
|
||||
dependencies:
|
||||
bytes "3.0.0"
|
||||
http-errors "1.6.2"
|
||||
iconv-lite "0.4.19"
|
||||
unpipe "1.0.0"
|
||||
|
||||
raw-body@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c"
|
||||
|
@ -19687,11 +19565,6 @@ react-element-to-jsx-string@^14.3.4:
|
|||
is-plain-object "5.0.0"
|
||||
react-is "17.0.2"
|
||||
|
||||
react-fast-marquee@^1.3.5:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/react-fast-marquee/-/react-fast-marquee-1.3.5.tgz#e53995027102fbec92da90606d7ca89703db9903"
|
||||
integrity sha512-eOqLoz4iVVBvi2wN/web8hd2XX9y2Z6CYR7g++7nTVHlTOXBtqyARQJ9rYNpbp179hAzloMx0yBFAo8LpNYmKQ==
|
||||
|
||||
react-feather@^2.0.10:
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/react-feather/-/react-feather-2.0.10.tgz#0e9abf05a66754f7b7bb71757ac4da7fb6be3b68"
|
||||
|
@ -19713,12 +19586,12 @@ react-gtm-module@^2.0.11:
|
|||
resolved "https://registry.yarnpkg.com/react-gtm-module/-/react-gtm-module-2.0.11.tgz#14484dac8257acd93614e347c32da9c5ac524206"
|
||||
integrity sha512-8gyj4TTxeP7eEyc2QKawEuQoAZdjKvMY4pgWfycGmqGByhs17fR+zEBs0JUDq4US/l+vbTl+6zvUIx27iDo/Vw==
|
||||
|
||||
react-hook-form@^7.31.1, react-hook-form@^7.34.2:
|
||||
react-hook-form@^7.33.1, react-hook-form@^7.34.2:
|
||||
version "7.34.2"
|
||||
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.34.2.tgz#9ac6d1a309a7c4aaa369d1269357a70e9e9bf4de"
|
||||
integrity sha512-1lYWbEqr0GW7HHUjMScXMidGvV0BE2RJV3ap2BL7G0EJirkqpccTaawbsvBO8GZaB3JjCeFBEbnEWI1P8ZoLRQ==
|
||||
|
||||
react-hot-toast@^2.1.1, react-hot-toast@^2.3.0:
|
||||
react-hot-toast@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.3.0.tgz#70b3d183ac2a4afb6b17cda4a7f4cfe02e730415"
|
||||
integrity sha512-/RxV+bfjld7tSJR1SCLzMAXgFuNW7fCpK6+vbYqfmbGSWcqTMz2rizrvfWKvtcPH5HK0NqxmBaC5SrAy1F42zA==
|
||||
|
@ -19800,11 +19673,6 @@ react-live-chat-loader@^2.7.3:
|
|||
resolved "https://registry.yarnpkg.com/react-live-chat-loader/-/react-live-chat-loader-2.7.3.tgz#a66a7d64eacdf0a680570b4e9a99639a88bffaae"
|
||||
integrity sha512-VviVqnF3PYDBJ77JiPZv4cpulx806L22WfsIQxvlxlEWmzKNp/0lEs57uP6EJcE+d1jQwGcR9DIsj5qouE6OkA==
|
||||
|
||||
react-masonry-css@^1.0.16:
|
||||
version "1.0.16"
|
||||
resolved "https://registry.yarnpkg.com/react-masonry-css/-/react-masonry-css-1.0.16.tgz#72b28b4ae3484e250534700860597553a10f1a2c"
|
||||
integrity sha512-KSW0hR2VQmltt/qAa3eXOctQDyOu7+ZBevtKgpNDSzT7k5LA/0XntNa9z9HKCdz3QlxmJHglTZ18e4sX4V8zZQ==
|
||||
|
||||
react-merge-refs@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06"
|
||||
|
@ -21079,11 +20947,6 @@ setimmediate@^1.0.4, setimmediate@^1.0.5:
|
|||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
|
||||
|
||||
setprototypeof@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
|
||||
integrity sha512-9jphSf3UbIgpOX/RKvX02iw/rN2TKdusnsPpGfO/rkcsrd+IRqgHZb4VGnmL0Cynps8Nj2hN45wsi30BzrHDIw==
|
||||
|
||||
setprototypeof@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
|
||||
|
@ -21523,7 +21386,7 @@ statuses@2.0.1, statuses@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
"statuses@>= 1.3.1 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
|
||||
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
@ -21870,7 +21733,7 @@ stripe@*:
|
|||
"@types/node" ">=8.1.0"
|
||||
qs "^6.10.3"
|
||||
|
||||
stripe@^9.1.0, stripe@^9.16.0:
|
||||
stripe@^9.16.0:
|
||||
version "9.16.0"
|
||||
resolved "https://registry.yarnpkg.com/stripe/-/stripe-9.16.0.tgz#94c24549c91fced457b9e3259e8a1a1bdb6dbd0e"
|
||||
integrity sha512-Dn8K+jSoQcXjxCobRI4HXUdHjOXsiF/KszK49fJnkbeCFjZ3EZxLG2JiM/CX+Hcq27NBDtv/Sxhvy+HhTmvyaQ==
|
||||
|
@ -22744,71 +22607,155 @@ turbo-android-arm64@1.4.3:
|
|||
resolved "https://registry.yarnpkg.com/turbo-android-arm64/-/turbo-android-arm64-1.4.3.tgz#d531c6935134d8cae9f31f61db47d13bd227bb93"
|
||||
integrity sha512-ZUvdoEHJkTkOFOO9PKWYrdONDBVqkNsvwEMufTVf07RXgqmbXDPkznzT4hcQm6xXyqWqJdjgSAMdlm+2nNE1Og==
|
||||
|
||||
turbo-darwin-64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.2.9.tgz#001159794757f77c4b016fc56d045c5e7bfc9510"
|
||||
integrity sha512-rVwDQpi6p0GwTiqSsvtA1b3RvKl8l2y+ElZ3EKGiIIJYZt1D6wBMJoADaZ9uZ/LWkT+WKfAWNtKdwRmuBAOS6g==
|
||||
|
||||
turbo-darwin-64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.4.3.tgz#123e214d9070ec6ac81468dc7a1cb02a459fafd7"
|
||||
integrity sha512-gapoVm5qbu2TJS4lJ6fM3o2eAkLyXSxHihw/4NRAYmwHCH3at1/cIAnRcctB/HLL3ZaB/p3HKb8mnI7k6xNHOw==
|
||||
|
||||
turbo-darwin-arm64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.2.9.tgz#fb19615984d1780fdcdd9e54a607efb46a700e72"
|
||||
integrity sha512-j7NgQHkQWWODw1I/saiqmjjD54uGAEq0qTTtLI3RoLaA+yI+awXmHwsiHRqsvGSyGJlBoKBcbxXkekLf21q3GA==
|
||||
|
||||
turbo-darwin-arm64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.4.3.tgz#9fa062c3ffa9208d0e2fa0155dcb48a290e7c109"
|
||||
integrity sha512-XUe6FTsHamEH7FfNslYYO04yecAaguhZuwW4kE9B/BAP8MUYsmVqONauLPyE/YqM6pf2K0xwVe+RlEGf53CWbg==
|
||||
|
||||
turbo-freebsd-64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-64/-/turbo-freebsd-64-1.2.9.tgz#edb2ee840ba80c257068e339d10ac460c1f9fb10"
|
||||
integrity sha512-+tLb3iCOrIeGrcOJZYey5mD9qgNgKYuwRRg6FeX/6TDITvZXcCS50A2uRbaD/PQzQKs1lHcshiCe/DRtbvJ63g==
|
||||
|
||||
turbo-freebsd-64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-64/-/turbo-freebsd-64-1.4.3.tgz#ffb4a939ca0000ec91114d2bbddc491c4835e862"
|
||||
integrity sha512-1CAjXmDClgMXdWZXreUfAbGBB2WB9TZHfJIdsgnDqt4fIcFGChknzYqc+Fj3tGHAczMpinGjBbWIzFuxOq/ofQ==
|
||||
|
||||
turbo-freebsd-arm64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.2.9.tgz#aebfb5b07a2dd6e9211fb6d9827c2f2288e2ca73"
|
||||
integrity sha512-gwI8jocTf036kc9GI1BebzftxrkT5pewHPA2iqvAXAJpX01G1x1iGcl8/uIbkbL5hp038nu+l2Kb+lRI96sJuA==
|
||||
|
||||
turbo-freebsd-arm64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.4.3.tgz#0bab3e2ccfac1ecc9ed9a30b0ab80f379fe3a788"
|
||||
integrity sha512-j5C7j/vwabPKpr5d6YlLgHGHBZCOcXj3HdkBshDHTQ0wghH0NuCUUaesYxI3wva/4/Ec0dhIrb20Laa/HMxXLA==
|
||||
|
||||
turbo-linux-32@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-32/-/turbo-linux-32-1.2.9.tgz#1462e45776d3ce93c57f2014745e7edb60910a44"
|
||||
integrity sha512-Rm47bIsCHIae/DkXJ58YrWvdh8o4Ug9U4VnTDb9byXrz2B7624ol9XdfpXv429z7LXkQR1+WnwCMwFB4K6DyuQ==
|
||||
|
||||
turbo-linux-32@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-32/-/turbo-linux-32-1.4.3.tgz#96deb5ebedfe6b97fd8ecc0fa40ff1c891c4c04f"
|
||||
integrity sha512-vnc+StXIoQEnxIU43j7rEz/J+v+RV4dbUdUolBq0k9gkUV8KMCcqPkIa753K47E2KLNGKXMaYDI6AHQX1GAQZg==
|
||||
|
||||
turbo-linux-64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.2.9.tgz#0eef4a6f6f267b773ea58c4bda86922092eda3eb"
|
||||
integrity sha512-8Gqi+TzEdmOmxxAukU0NO0JlIqdm98C97u9qEsxWrXTFL/xL21gKCixqsBTEO7JOISC4M8VjArxjSsITRbkD5g==
|
||||
|
||||
turbo-linux-64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.4.3.tgz#ed0152e724c78dea090b2d60d29258110bdfb14a"
|
||||
integrity sha512-KAUeIa8Ejt6BLrBGbVurlrjDxqh62tu75D4cqKqKfzWspcbEtmdqlV6qthXfm8SlzGSNuQXX0+qXEWds2FIZXg==
|
||||
|
||||
turbo-linux-arm64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.2.9.tgz#57777d356bf74ef2cc284998ef86fe19c77b92c2"
|
||||
integrity sha512-FVIeM7koUtyu1cNAJhPYjb90kL/ICdWoJr4PoZZYnqty5sxLsBg75bVErEDQeDzKQvwXLlcax2lEzHvaSyn/wg==
|
||||
|
||||
turbo-linux-arm64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.4.3.tgz#74fac47575e6b5af5830d26a56493859d09e4c7c"
|
||||
integrity sha512-rzB7w+RHCQkKr8aDxxozv/IzdN976CYyBiRocSf9QGU73uyAg8pCo3i0MiENSRjDC+tUbdbu2lEUwGXf9ziB9Q==
|
||||
|
||||
turbo-linux-arm@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm/-/turbo-linux-arm-1.2.9.tgz#2424016fb926143682f9029bd86a8d455979e075"
|
||||
integrity sha512-OS+XCWiGFbuM7UNBVQdVbIJqxhVu9Sr2WxQgDcGZpCYn32yLLPlWDDGL0Cl/EG006J9k+VS1e4OzyM6kfMxS9Q==
|
||||
|
||||
turbo-linux-arm@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm/-/turbo-linux-arm-1.4.3.tgz#ac42b3c5918fe06270cb8dfbe31442a48cc38fc3"
|
||||
integrity sha512-zZNoHUK5ioFyxAngh8tHe763Dzb22ne3LJkaZn0ExkFHJtWClWv536lPcDuQPpIH9W9iz5OwPKtN32DNpNwk8A==
|
||||
|
||||
turbo-linux-mips64le@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-mips64le/-/turbo-linux-mips64le-1.2.9.tgz#e3bb35f53cb84ff836cf42fc576b6197c92a5e8a"
|
||||
integrity sha512-2zVBnOVivWGpl51qO/lycfw7euM4b04AXYUmhsWkUN3FygIwyNgjuiMU8rxQOlu9VGX8X+WXkX2gfbgTovTeFw==
|
||||
|
||||
turbo-linux-mips64le@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-mips64le/-/turbo-linux-mips64le-1.4.3.tgz#d796261795e4fc29935cbffdadfbc11d83cbe616"
|
||||
integrity sha512-Ztr1BM5NiUsHWjB7zpkP2RpRDA/fjbLaCbkyfyGlLmVkrSkh05NFBD03IWs2LSLy/wb6vRpL3MQ4FKcb97Tn8w==
|
||||
|
||||
turbo-linux-ppc64le@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.2.9.tgz#130041711579a1b6b3fe774d85c394425d45c0ac"
|
||||
integrity sha512-EGgKyzf8IhodOF32BvE3Zlgbr/dSGuUbemC9RGSuhF1F1PMnP1nYS/t3JWN5QKZU4O2uWiIyLdC/0ZjtcGAcZQ==
|
||||
|
||||
turbo-linux-ppc64le@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.4.3.tgz#b7d043efa27290e074b7aba45bb298fc86bd8cfe"
|
||||
integrity sha512-tJaFJWxwfy/iLd69VHZj6JcXy9hO8LQ+ZUOna/p/wiy5WrFVgEYlD+4gfECfRZ+52EIelMgXl97vACaN1WMhLw==
|
||||
|
||||
turbo-windows-32@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-32/-/turbo-windows-32-1.2.9.tgz#89a0d8463dffba01627d69998bfe6ea5fa975511"
|
||||
integrity sha512-XrMJMUtewlfksBUB0R7Tyw16IoqshVl6f/3R2ccMccddEMcvak0oW03FK9n+Y4F+wyIoJ22AVhu8jMv+HgEehA==
|
||||
|
||||
turbo-windows-32@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-32/-/turbo-windows-32-1.4.3.tgz#3dac4678f1d74ccf0ac187e738d30a557932fbad"
|
||||
integrity sha512-w9LyYd+DW3PYFXu9vQiie5lfdqmVIKLV0h181C49hempkIXfgQAosXfaugYWDwBc0GEBoBIQB0vGQKE7gt5nzA==
|
||||
|
||||
turbo-windows-64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.2.9.tgz#a55e3f32996ce4a8a538f9667748e7a1129ed10e"
|
||||
integrity sha512-ewhj4MrqcMpW/keag4xG7YRLTJ7PzcqBc6Kc96OGD2qfK/uJV/r7H3Xt09WuYHRWwPgGEeNn8utpqdqbYfCVDw==
|
||||
|
||||
turbo-windows-64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.4.3.tgz#b493ab62db70c4c147cf0dc56dc812ea2e15cf3c"
|
||||
integrity sha512-qPCqemxxOrXyqqig3fVQozRkOwo5oJSsQ3FTZE5YlNu2NwwWvY1mC0X4WTZIDsbj4oHqr0riqC7RGKbjQm1IIQ==
|
||||
|
||||
turbo-windows-arm64@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.2.9.tgz#3dc635c0031a0998be0322f9a258553f7cb4eb6e"
|
||||
integrity sha512-B8BoNb/yZWAyKwQUbs2+UFzLmOu/WGv/+ADT6SQfI8jOaTenS7Od4bbMsGJT0iXcqv+v8TcWKX83KmQ6gxBQpg==
|
||||
|
||||
turbo-windows-arm64@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.4.3.tgz#be4b38994cb3f1ceb36940ff6d6b227fa2ba53bf"
|
||||
integrity sha512-djnOOBjw33AnUx2SR6TMOpDr3nKLnVD+HcZvnQz70HyE331AKWjBoEE4rtUOteLAfViWAp3afbiljFSOnbU00Q==
|
||||
|
||||
turbo@1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.2.9.tgz#61257149a2a29966c9941a16e0b5ad88b07b4e79"
|
||||
integrity sha512-aPGzZqmUHE9yx9TS7wcAJnDmXiuQSNXDwU5b1KrgNlFuID18TL443wna79p7k4awmf4Yuhu1cSZIvO+se72iVQ==
|
||||
optionalDependencies:
|
||||
turbo-darwin-64 "1.2.9"
|
||||
turbo-darwin-arm64 "1.2.9"
|
||||
turbo-freebsd-64 "1.2.9"
|
||||
turbo-freebsd-arm64 "1.2.9"
|
||||
turbo-linux-32 "1.2.9"
|
||||
turbo-linux-64 "1.2.9"
|
||||
turbo-linux-arm "1.2.9"
|
||||
turbo-linux-arm64 "1.2.9"
|
||||
turbo-linux-mips64le "1.2.9"
|
||||
turbo-linux-ppc64le "1.2.9"
|
||||
turbo-windows-32 "1.2.9"
|
||||
turbo-windows-64 "1.2.9"
|
||||
turbo-windows-arm64 "1.2.9"
|
||||
|
||||
turbo@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.4.3.tgz#7221972f47a28bfcb53609e97db9810d2c3a265b"
|
||||
|
@ -22987,11 +22934,6 @@ typeorm@0.2.41:
|
|||
yargs "^17.0.1"
|
||||
zen-observable-ts "^1.0.0"
|
||||
|
||||
typescript@^4.6.4:
|
||||
version "4.8.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790"
|
||||
integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==
|
||||
|
||||
typescript@^4.7.4:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
|
@ -24667,16 +24609,16 @@ zod-prisma@^0.5.4:
|
|||
parenthesis "^3.1.8"
|
||||
ts-morph "^13.0.2"
|
||||
|
||||
zod@^3.16.0, zod@^3.18.0:
|
||||
version "3.18.0"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.18.0.tgz#2eed58b3cafb8d9a67aa2fee69279702f584f3bc"
|
||||
integrity sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==
|
||||
|
||||
zod@^3.17.3:
|
||||
version "3.17.3"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba"
|
||||
integrity sha512-4oKP5zvG6GGbMlqBkI5FESOAweldEhSOZ6LI6cG+JzUT7ofj1ZOC0PJudpQOpT1iqOFpYYtX5Pw0+o403y4bcg==
|
||||
|
||||
zod@^3.18.0:
|
||||
version "3.18.0"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.18.0.tgz#2eed58b3cafb8d9a67aa2fee69279702f584f3bc"
|
||||
integrity sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==
|
||||
|
||||
zwitch@^1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"
|
||||
|
|
Loading…
Reference in New Issue
Block a user