snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
6
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/.eslintrc.js
vendored
Normal file
6
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/.eslintrc.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
};
|
||||
51
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/e2e/smoke.cy.ts
vendored
Normal file
51
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/e2e/smoke.cy.ts
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
describe("smoke tests", () => {
|
||||
afterEach(() => {
|
||||
cy.cleanupUser();
|
||||
});
|
||||
|
||||
it("should allow you to register and login", () => {
|
||||
const loginForm = {
|
||||
email: `${faker.internet.userName()}@example.com`,
|
||||
password: faker.internet.password(),
|
||||
};
|
||||
|
||||
cy.then(() => ({ email: loginForm.email })).as("user");
|
||||
|
||||
cy.visitAndCheck("/");
|
||||
|
||||
cy.findByRole("link", { name: /sign up/i }).click();
|
||||
|
||||
cy.findByRole("textbox", { name: /email/i }).type(loginForm.email);
|
||||
cy.findByLabelText(/password/i).type(loginForm.password);
|
||||
cy.findByRole("button", { name: /create account/i }).click();
|
||||
|
||||
cy.findByRole("link", { name: /notes/i }).click();
|
||||
cy.findByRole("button", { name: /logout/i }).click();
|
||||
cy.findByRole("link", { name: /log in/i });
|
||||
});
|
||||
|
||||
it("should allow you to make a note", () => {
|
||||
const testNote = {
|
||||
title: faker.lorem.words(1),
|
||||
body: faker.lorem.sentences(1),
|
||||
};
|
||||
cy.login();
|
||||
|
||||
cy.visitAndCheck("/");
|
||||
|
||||
cy.findByRole("link", { name: /notes/i }).click();
|
||||
cy.findByText("No notes yet");
|
||||
|
||||
cy.findByRole("link", { name: /\+ new note/i }).click();
|
||||
|
||||
cy.findByRole("textbox", { name: /title/i }).type(testNote.title);
|
||||
cy.findByRole("textbox", { name: /body/i }).type(testNote.body);
|
||||
cy.findByRole("button", { name: /save/i }).click();
|
||||
|
||||
cy.findByRole("button", { name: /delete/i }).click();
|
||||
|
||||
cy.findByText("No notes yet");
|
||||
});
|
||||
});
|
||||
5
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/fixtures/example.json
vendored
Normal file
5
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/fixtures/example.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
98
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/commands.ts
vendored
Normal file
98
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/commands.ts
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Cypress {
|
||||
interface Chainable {
|
||||
/**
|
||||
* Logs in with a random user. Yields the user and adds an alias to the user
|
||||
*
|
||||
* @returns {typeof login}
|
||||
* @memberof Chainable
|
||||
* @example
|
||||
* cy.login()
|
||||
* @example
|
||||
* cy.login({ email: 'whatever@example.com' })
|
||||
*/
|
||||
login: typeof login;
|
||||
|
||||
/**
|
||||
* Deletes the current @user
|
||||
*
|
||||
* @returns {typeof cleanupUser}
|
||||
* @memberof Chainable
|
||||
* @example
|
||||
* cy.cleanupUser()
|
||||
* @example
|
||||
* cy.cleanupUser({ email: 'whatever@example.com' })
|
||||
*/
|
||||
cleanupUser: typeof cleanupUser;
|
||||
|
||||
/**
|
||||
* Extends the standard visit command to wait for the page to load
|
||||
*
|
||||
* @returns {typeof visitAndCheck}
|
||||
* @memberof Chainable
|
||||
* @example
|
||||
* cy.visitAndCheck('/')
|
||||
* @example
|
||||
* cy.visitAndCheck('/', 500)
|
||||
*/
|
||||
visitAndCheck: typeof visitAndCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function login({
|
||||
email = faker.internet.email({ provider: "example.com" }),
|
||||
}: {
|
||||
email?: string;
|
||||
} = {}) {
|
||||
cy.then(() => ({ email })).as("user");
|
||||
cy.exec(
|
||||
`npx ts-node -r tsconfig-paths/register ./cypress/support/create-user.ts "${email}"`,
|
||||
).then(({ stdout }) => {
|
||||
const cookieValue = stdout
|
||||
.replace(/.*<cookie>(?<cookieValue>.*)<\/cookie>.*/s, "$<cookieValue>")
|
||||
.trim();
|
||||
cy.setCookie("__session", cookieValue);
|
||||
});
|
||||
return cy.get("@user");
|
||||
}
|
||||
|
||||
function cleanupUser({ email }: { email?: string } = {}) {
|
||||
if (email) {
|
||||
deleteUserByEmail(email);
|
||||
} else {
|
||||
cy.get("@user").then((user) => {
|
||||
const email = (user as { email?: string }).email;
|
||||
if (email) {
|
||||
deleteUserByEmail(email);
|
||||
}
|
||||
});
|
||||
}
|
||||
cy.clearCookie("__session");
|
||||
}
|
||||
|
||||
function deleteUserByEmail(email: string) {
|
||||
cy.exec(
|
||||
`npx ts-node -r tsconfig-paths/register ./cypress/support/delete-user.ts "${email}"`,
|
||||
);
|
||||
cy.clearCookie("__session");
|
||||
}
|
||||
|
||||
// We're waiting a second because of this issue happen randomly
|
||||
// https://github.com/cypress-io/cypress/issues/7306
|
||||
// Also added custom types to avoid getting detached
|
||||
// https://github.com/cypress-io/cypress/issues/7306#issuecomment-1152752612
|
||||
// ===========================================================
|
||||
function visitAndCheck(url: string, waitTime = 1000) {
|
||||
cy.visit(url);
|
||||
cy.location("pathname").should("contain", url).wait(waitTime);
|
||||
}
|
||||
|
||||
export const registerCommands = () => {
|
||||
Cypress.Commands.add("login", login);
|
||||
Cypress.Commands.add("cleanupUser", cleanupUser);
|
||||
Cypress.Commands.add("visitAndCheck", visitAndCheck);
|
||||
};
|
||||
48
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/create-user.ts
vendored
Normal file
48
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/create-user.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Use this to create a new user and login with that user
|
||||
// Simply call this with:
|
||||
// npx ts-node -r tsconfig-paths/register ./cypress/support/create-user.ts username@example.com,
|
||||
// and it will log out the cookie value you can use to interact with the server
|
||||
// as that new user.
|
||||
|
||||
import { installGlobals } from "@remix-run/node";
|
||||
import { parse } from "cookie";
|
||||
|
||||
import { createUser } from "~/models/user.server";
|
||||
import { createUserSession } from "~/session.server";
|
||||
|
||||
installGlobals();
|
||||
|
||||
async function createAndLogin(email: string) {
|
||||
if (!email) {
|
||||
throw new Error("email required for login");
|
||||
}
|
||||
if (!email.endsWith("@example.com")) {
|
||||
throw new Error("All test emails must end in @example.com");
|
||||
}
|
||||
|
||||
const user = await createUser(email, "myreallystrongpassword");
|
||||
|
||||
const response = await createUserSession({
|
||||
request: new Request("test://test"),
|
||||
userId: user.id,
|
||||
remember: false,
|
||||
redirectTo: "/",
|
||||
});
|
||||
|
||||
const cookieValue = response.headers.get("Set-Cookie");
|
||||
if (!cookieValue) {
|
||||
throw new Error("Cookie missing from createUserSession response");
|
||||
}
|
||||
const parsedCookie = parse(cookieValue);
|
||||
// we log it like this so our cypress command can parse it out and set it as
|
||||
// the cookie value.
|
||||
console.log(
|
||||
`
|
||||
<cookie>
|
||||
${parsedCookie.__session}
|
||||
</cookie>
|
||||
`.trim(),
|
||||
);
|
||||
}
|
||||
|
||||
createAndLogin(process.argv[2]);
|
||||
37
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/delete-user.ts
vendored
Normal file
37
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/delete-user.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Use this to delete a user by their email
|
||||
// Simply call this with:
|
||||
// npx ts-node -r tsconfig-paths/register ./cypress/support/delete-user.ts username@example.com,
|
||||
// and that user will get deleted
|
||||
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
||||
import { installGlobals } from "@remix-run/node";
|
||||
|
||||
import { prisma } from "~/db.server";
|
||||
|
||||
installGlobals();
|
||||
|
||||
async function deleteUser(email: string) {
|
||||
if (!email) {
|
||||
throw new Error("email required for login");
|
||||
}
|
||||
if (!email.endsWith("@example.com")) {
|
||||
throw new Error("All test emails must end in @example.com");
|
||||
}
|
||||
|
||||
try {
|
||||
await prisma.user.delete({ where: { email } });
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof PrismaClientKnownRequestError &&
|
||||
error.code === "P2025"
|
||||
) {
|
||||
console.log("User not found, so no need to delete");
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
deleteUser(process.argv[2]);
|
||||
17
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/e2e.ts
vendored
Normal file
17
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/support/e2e.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import "@testing-library/cypress/add-commands";
|
||||
import { registerCommands } from "./commands";
|
||||
|
||||
registerCommands();
|
||||
|
||||
Cypress.on("uncaught:exception", (err) => {
|
||||
// Cypress and React Hydrating the document don't get along
|
||||
// for some unknown reason. Hopefully we figure out why eventually
|
||||
// so we can remove this.
|
||||
if (
|
||||
/hydrat/i.test(err.message) ||
|
||||
/Minified React error #418/.test(err.message) ||
|
||||
/Minified React error #423/.test(err.message)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
28
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/tsconfig.json
vendored
Normal file
28
packages/shadcn/test/fixtures/frameworks/remix-indie-stack/cypress/tsconfig.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"exclude": [
|
||||
"../node_modules/@types/jest",
|
||||
"../node_modules/@testing-library/jest-dom"
|
||||
],
|
||||
"include": [
|
||||
"e2e/**/*",
|
||||
"support/**/*",
|
||||
"../node_modules/cypress",
|
||||
"../node_modules/@testing-library/cypress"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"noEmit": true,
|
||||
"types": ["node", "cypress", "@testing-library/cypress"],
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "Bundler",
|
||||
"target": "ES2020",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true,
|
||||
|
||||
"paths": {
|
||||
"~/*": ["../app/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user