Skip to content

Commit

Permalink
test: Smoke Tests for packaged embeds and build improvements (calcom#…
Browse files Browse the repository at this point in the history
…9169)

* Fix 2 Factor Auth

* Add a sandbox to verify types of embed-react

* Add fault types location

* Fix type location again

* Break types

* Ensure that builds are done again when doing pbublish

* Debug failure in CI

* Make sure unit test files arent used by playwright

* Fix embed-react test description

* Update .github/workflows/e2e-embed-react.yml

Co-authored-by: Omar López <[email protected]>

* Remove unnecessary log

---------

Co-authored-by: Alex van Andel <[email protected]>
Co-authored-by: Omar López <[email protected]>
  • Loading branch information
3 people authored Jun 1, 2023
1 parent 484f603 commit a0bf5b4
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 48 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/e2e-embed-react.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ jobs:
- uses: ./.github/actions/cache-db
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn test-e2e:embed-react
run: |
yarn test-e2e:embed-react
yarn workspace @calcom/embed-react packaged:tests
env:
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
- name: Upload Test Results
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"app-store": "yarn app-store-cli cli",
"create-app": "yarn app-store create",
"edit-app": "yarn app-store edit",
"publish-embed": "yarn workspaces foreach --from=\"@calcom/embed*\" npm publish --access=public",
"withEmbedPublishEnv": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn",
"publish-embed": "yarn withEmbedPublishEnv workspace @calcom/embed-core build && yarn withEmbedPublishEnv workspace @calcom/embed-snippet build && yarn workspaces foreach --from=\"@calcom/embed*\" npm publish --access=public",
"delete-app": "yarn app-store delete",
"create-app-template": "yarn app-store create-template",
"edit-app-template": "yarn app-store edit-template",
Expand Down
5 changes: 3 additions & 2 deletions packages/embeds/embed-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"embed-web-start": "yarn workspace @calcom/web start",
"__build": "yarn tailwind && vite build && tsc --emitDeclarationOnly --declarationDir dist && cp -r ../../../apps/web/public/embed ./dist/",
"__dev": "yarn tailwind && vite build --mode development",
"build": "NEXT_PUBLIC_EMBED_FINGER_PRINT=$(git rev-parse --short HEAD) yarn __build",
"build": "rm -rf dist && NEXT_PUBLIC_EMBED_FINGER_PRINT=$(git rev-parse --short HEAD) yarn __build",
"build-preview": "PREVIEW_BUILD=1 yarn __build ",
"vite": "vite",
"tailwind": "yarn tailwindcss -i ./src/styles.css -o ./src/tailwind.generated.css",
Expand All @@ -29,7 +29,8 @@
"embed-tests": "yarn playwright test --config=playwright/config/playwright.config.ts",
"embed-tests-quick": "QUICK=true yarn embed-tests",
"embed-tests-update-snapshots:ci": "yarn embed-tests-quick --update-snapshots",
"prepack": "NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn build",
"withEmbedPublishEnv": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn",
"prepack": "yarn withEmbedPublishEnv build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf ../../../apps/web/public/embed"
},
"files": [
Expand Down
4 changes: 2 additions & 2 deletions packages/embeds/embed-core/playwright/lib/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ export async function bookFirstEvent(username: string, frame: Frame, page: Page)
return booking;
}

export async function rescheduleEvent(username, frame, page) {
export async function rescheduleEvent(username: string, frame: Frame, page: Page) {
await selectFirstAvailableTimeSlotNextMonth(frame, page);
await frame.waitForURL((url) => {
await frame.waitForURL((url: { pathname: string | string[] }) => {
return url.pathname.includes(`/${username}/book`);
});
// --- fill form
Expand Down
10 changes: 8 additions & 2 deletions packages/embeds/embed-core/src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ type SingleInstruction = SingleInstructionMap[keyof SingleInstructionMap];
export type Instruction = SingleInstruction | SingleInstruction[];
export type InstructionQueue = Instruction[];

type PrefillAndIframeAttrsConfig = Record<string, string | string[] | Record<string, string>> & {
export type PrefillAndIframeAttrsConfig = Record<string, string | string[] | Record<string, string>> & {
iframeAttrs?: Record<string, string> & {
id?: string;
};
Expand Down Expand Up @@ -551,7 +551,13 @@ class CalApi {
this.cal.actionManager.on(action, callback);
}

off({ action, callback }: { action: never; callback: never }) {
off<T extends keyof EventDataMap>({
action,
callback,
}: {
action: T;
callback: (arg0: CustomEvent<EventData<T>>) => void;
}) {
this.cal.actionManager.off(action, callback);
}

Expand Down
7 changes: 5 additions & 2 deletions packages/embeds/embed-react/inline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import { useEffect } from "react";
import { useState } from "react";
import ReactDom from "react-dom";

// Because we don't import from @calcom/embed-react, this file isn't able to test if the build is successful or not and thus npm package would work or not correctly.
// There are tests in test/built which verifiy that the types from built package are correctly generated and exported correctly.
import Cal, { getCalApi } from "./src/index";

const api = getCalApi();

function App() {
const [loaded, setLoaded] = useState(false);
const [, setLoaded] = useState(false);
useEffect(() => {
// Simulate state change causing config object to change, causing rerender of Cal
setTimeout(setLoaded.bind(true), 1000);
const callback = (event) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const callback = (event: any) => {
console.log(event.detail);
};
api.then((api) => {
Expand Down
7 changes: 4 additions & 3 deletions packages/embeds/embed-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
},
"scripts": {
"dev": "vite --port=3101 --open",
"build": "vite build && tsc --emitDeclarationOnly --declarationDir dist",
"build": "rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationDir dist",
"preview": "vite preview",
"prepare": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn build",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint --ext .ts,.js,.tsx,.jsx ./src",
"embed-tests": "yarn playwright test --config=./playwright/config/playwright.config.ts",
"embed-tests-quick": "QUICK=true yarn embed-tests",
"embed-tests-update-snapshots:ci": "yarn embed-tests-quick --update-snapshots",
"prepack": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn build",
"packaged:tests": "cd test/packaged && yarn tsc --noEmit && yarn run -T test -- --packaged-embed-tests-only",
"withEmbedPublishEnv": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn",
"prepack": "yarn withEmbedPublishEnv build && yarn packaged:tests",
"embed-web-start": "yarn workspace @calcom/web start",
"embed-dev": "yarn workspace @calcom/embed-react dev",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
Expand Down
28 changes: 17 additions & 11 deletions packages/embeds/embed-react/playwright/tests/basic.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ import { expect } from "@playwright/test";
import { getEmbedIframe } from "@calcom/embed-core/playwright/lib/testUtils";
import { test } from "@calcom/web/playwright/lib/fixtures";

test("Inline Usage Snapshot", async ({ page, getActionFiredDetails, addEmbedListeners }) => {
//TODO: Do it with page.goto automatically
await addEmbedListeners("");
await page.goto("/");
const embedIframe = await getEmbedIframe({ page, pathname: "/pro" });
expect(embedIframe).toBeEmbedCalLink("", getActionFiredDetails, {
pathname: "/pro",
searchParams: {
theme: "dark",
},
test.describe("Inline Embed", () => {
test("should verify that the iframe got created with correct URL", async ({
page,
getActionFiredDetails,
addEmbedListeners,
}) => {
//TODO: Do it with page.goto automatically
await addEmbedListeners("");
await page.goto("/");
const embedIframe = await getEmbedIframe({ page, pathname: "/pro" });
expect(embedIframe).toBeEmbedCalLink("", getActionFiredDetails, {
pathname: "/pro",
searchParams: {
theme: "dark",
},
});
// expect(await page.screenshot()).toMatchSnapshot("react-component-inline.png");
});
// expect(await page.screenshot()).toMatchSnapshot("react-component-inline.png");
});
4 changes: 3 additions & 1 deletion packages/embeds/embed-react/src/Cal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import { useEffect, useRef } from "react";

import type { PrefillAndIframeAttrsConfig } from "@calcom/embed-core";

import useEmbed from "./useEmbed";

type CalProps = {
Expand All @@ -11,7 +13,7 @@ type CalProps = {
debug?: boolean;
uiDebug?: boolean;
};
config?: Record<string, string>;
config?: PrefillAndIframeAttrsConfig;
embedJsUrl?: string;
} & React.HTMLAttributes<HTMLDivElement>;

Expand Down
5 changes: 5 additions & 0 deletions packages/embeds/embed-react/test/packaged/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Packaged

The tests in this file are run on the packaged code that is published to npm. The packaged code is different from the source code in atleast the following ways
- Not all files go to packaged code.If package.json -> files field is specified then only the files that are specified there would be published. So, one might accidentally miss an important file that's available otherwise.
- The packaged code doesn't have .ts files. Those files are actually converted to .js files and .d.ts files are generated separately for TypeScript support. It allows the package to work in both TypeScript and non TypeScript environments.
16 changes: 16 additions & 0 deletions packages/embeds/embed-react/test/packaged/api.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @fileoverview
* This file tests two things in 2 ways
* - It is a vitest test file and thus it tests if the code executes without any error. Thus, it tests that package.json->main/module fields are correctly defined. It obviously verifies the assertions as well.
* - It is also validates for it's types and thus verifies that @calcom/embed-react has correctly specified it's types in package.json->types field.
*/
import { expect, test } from "vitest";

// This import may show up as an error in your IDE, but it's fine because typings are available only after embed-react is built.
import { getCalApi } from "@calcom/embed-react";

const api = getCalApi();

test("Check that the API is available", () => {
expect(api).toBeDefined()
});
14 changes: 14 additions & 0 deletions packages/embeds/embed-react/test/packaged/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "@calcom/tsconfig/base.json",
"compilerOptions": {
"module": "ESNext",
"target": "ES2015",
"moduleResolution": "Node",
"baseUrl": ".",
"declaration": true,
"jsx": "preserve",
"outDir": "dist",
},
"include": ["**/*.ts"],
}

5 changes: 3 additions & 2 deletions packages/embeds/embed-react/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@calcom/embed-snippet": ["../embed-snippet/src"]
}
},
"include": ["src", "env.d.ts"],
"exclude": ["dist", "build", "node_modules", "test-cal.tsx"]
"include": ["**/*.ts","**/*.tsx", "env.d.ts"],
// Exclude "test" because that has `api.test.ts` which imports @calcom/embed-react which needs it to be built using this tsconfig.json first. Excluding it here prevents type-check from validating test folder
"exclude": ["node_modules", "test"]
}
5 changes: 3 additions & 2 deletions packages/embeds/embed-snippet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
"directory": "packages/embeds/embed-snippet"
},
"scripts": {
"build": "vite build && tsc --emitDeclarationOnly --declarationDir dist",
"build": "rm -rf dist && vite build && tsc --emitDeclarationOnly --declarationDir dist",
"type-check": "tsc --pretty --noEmit",
"type-check:ci": "tsc-absolute --pretty --noEmit",
"lint": "eslint --ext .ts,.js src",
"prepack": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn build",
"withEmbedPublishEnv": "NEXT_PUBLIC_EMBED_LIB_URL='https://app.cal.com/embed/embed.js' NEXT_PUBLIC_WEBAPP_URL='https://app.cal.com' yarn",
"prepack": "yarn withEmbedPublishEnv build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
},
"files": [
Expand Down
4 changes: 2 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const config: PlaywrightTestConfig = {
{
name: "@calcom/embed-core",
testDir: "./packages/embeds/embed-core/",
testMatch: /.*\.(e2e|test)\.tsx?/,
testMatch: /.*\.e2e\.tsx?/,
expect: {
timeout: DEFAULT_EXPECT_TIMEOUT,
},
Expand All @@ -116,7 +116,7 @@ const config: PlaywrightTestConfig = {
expect: {
timeout: DEFAULT_EXPECT_TIMEOUT,
},
testMatch: /.*\.(e2e|test)\.tsx?/,
testMatch: /.*\.e2e\.tsx?/,
use: { ...devices["Desktop Chrome"], baseURL: "http://localhost:3101/" },
},
{
Expand Down
46 changes: 29 additions & 17 deletions vitest.workspace.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import { defineWorkspace } from "vitest/config";

const packagedEmbedTestsOnly = process.argv.includes("--packaged-embed-tests-only");
// defineWorkspace provides a nice type hinting DX
export default defineWorkspace([
{
test: {
include: ["packages/**/*.{test,spec}.{ts,js}", "apps/**/*.{test,spec}.{ts,js}"],
// TODO: Ignore the api until tests are fixed
exclude: ["apps/api/**/*", "**/node_modules/**/*"],
},
},
{
test: {
name: "@calcom/closecom",
include: ["packages/app-store/closecom/**/*.{test,spec}.{ts,js}"],
environment: "jsdom",
setupFiles: ["packages/app-store/closecom/test/globals.ts"],
},
},
]);
const workspaces = packagedEmbedTestsOnly
? [
{
test: {
include: ["packages/embeds/**/*.{test,spec}.{ts,js}"],
environment: "jsdom",
},
},
]
: [
{
test: {
include: ["packages/**/*.{test,spec}.{ts,js}", "apps/**/*.{test,spec}.{ts,js}"],
// TODO: Ignore the api until tests are fixed
exclude: ["apps/api/**/*", "**/node_modules/**/*", "packages/embeds/**/*"],
},
},
{
test: {
name: "@calcom/closecom",
include: ["packages/app-store/closecom/**/*.{test,spec}.{ts,js}"],
environment: "jsdom",
setupFiles: ["packages/app-store/closecom/test/globals.ts"],
},
},
];

export default defineWorkspace(workspaces);

0 comments on commit a0bf5b4

Please sign in to comment.