-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(validation): UI for interacting with
/api/validate
endpoint (#5)
* - Added CSS file rules for editorconfig (2-indent) - Made background a little lighter * Added main content container to root layout * Initial UI for interacting with the validate API endpoint * Added htmlFor to loading textarea to fix build * Turn off the 'react/display-name' linting rule to allow for loading components via a .Loading attribute * Fix bottom padding of option label * Added empty default string values to additional classname parameters to avoid undefined classnames * Install Cypress * Initial workflow for E2E testing for the preview branch * Specify baseUrl via config instead of env var * - Update setup-go action version 4 -> 5 - Use cache in initial dependency installation job - Don't install in final e2e testing stage - Add install-deps as a dependency of the test-preview stage * - Remove lookup-only from initial dep cache - Add Cypress binary to cache * Run E2E test against per-deployment URLs (allows for concurrent/cross-branch execution of e2e tests) * Fix saving preview URL to GitHub output * Add Cypress component config * Initial component tests * Add component tests to CI * Don't deploy unless component tests pass * Add required testId to TextArea component * E2E test * - Use beforeEach in component test to enforce DRY - Change wording of "show excluded" to "show ignored" - Added data-cy tags to options area and submit button * - Added new testing commands - Updated docs for testing
- Loading branch information
1 parent
18ab30a
commit 0116624
Showing
20 changed files
with
2,297 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
"extends": "next/core-web-vitals", | ||
"rules": { | ||
"react/display-name": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { defineConfig } from "cypress"; | ||
|
||
export default defineConfig({ | ||
e2e: { | ||
baseUrl: "http://localhost:3000", | ||
setupNodeEvents(on, config) { | ||
// implement node event listeners here | ||
}, | ||
}, | ||
|
||
component: { | ||
devServer: { | ||
framework: "next", | ||
bundler: "webpack", | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
describe("Homepage", () => { | ||
beforeEach(() => { | ||
cy.visit("/"); | ||
}); | ||
|
||
it("should have all inputs present and in the correct initial state", () => { | ||
// Test inputs are present and valid | ||
cy.get("[data-cy=dockerignore-input] > textarea") | ||
.should("exist") | ||
.and("be.enabled"); | ||
cy.get("[data-cy=dockerignore-input] > label") | ||
.should("exist") | ||
.and("have.text", ".dockerignore"); | ||
|
||
cy.get("[data-cy=files-input] > textarea") | ||
.should("exist") | ||
.and("be.enabled"); | ||
cy.get("[data-cy=files-input] > label") | ||
.should("exist") | ||
.and("have.text", "Files"); | ||
|
||
cy.get("[data-cy=options] > input[name=showIgnored]") | ||
.should("exist") | ||
.and("be.checked"); | ||
|
||
cy.get("[data-cy=validate-button]").should("exist").and("be.enabled"); | ||
|
||
// Test output is present and in the correct state | ||
cy.get("[data-cy=result-output] > textarea") | ||
.should("exist") | ||
.and("be.disabled"); | ||
cy.get("[data-cy=result-output] > label") | ||
.should("exist") | ||
.and("have.text", "Ignored Files"); | ||
}); | ||
|
||
it("should allow form submission with correct ", () => { | ||
const dockerignore = "node_modules"; | ||
const files = "node_modules\npackage.json"; | ||
|
||
// Output text with "Show ignored files" checked | ||
const expectedIgnoredOutput = "node_modules"; | ||
// Output text with "Show ignored files" unchecked | ||
const expectedCopyFilesOutput = "package.json"; | ||
// API Response | ||
const expectedRes = [true, false]; | ||
|
||
// Ensure the correct data is being sent and received | ||
cy.intercept("POST", "/api/validate", (req) => { | ||
expect(JSON.parse(req.body)).to.deep.equal({ | ||
dockerignore: ["node_modules"], | ||
files: ["node_modules", "package.json"], | ||
}); | ||
req.continue((res) => { | ||
expect(res.statusCode).to.equal(200); | ||
expect(res.body).to.deep.equal(expectedRes); | ||
}); | ||
}).as("validate"); | ||
|
||
cy.get("[data-cy=dockerignore-input] > textarea").type(dockerignore); | ||
cy.get("[data-cy=files-input] > textarea").type(files); | ||
|
||
// Ensure the output is empty and the loading state is not present | ||
cy.get("[data-cy=result-output] > textarea").should("be.empty"); | ||
cy.get("[data-cy=textarea-loading]").should("not.exist"); | ||
|
||
// Once clicked, the result should be replaced with a loading state | ||
cy.get("[data-cy=validate-button]").click(); | ||
cy.get("[data-cy=result-output]").should("not.exist"); | ||
cy.get("[data-cy=textarea-loading]").should("exist"); | ||
cy.get("[data-cy=textarea-loading] > label").should( | ||
"have.text", | ||
"Matching patterns..." | ||
); | ||
|
||
cy.wait("@validate"); | ||
|
||
// Loading state should be removed and the result should be present | ||
cy.get("[data-cy=textarea-loading]").should("not.exist"); | ||
cy.get("[data-cy=result-output]").should("exist"); | ||
|
||
// Ensure the result has the correct output for both checked | ||
// and unchecked states of "Show ignored files" | ||
cy.get("[data-cy=result-output] > textarea").should( | ||
"have.text", | ||
expectedIgnoredOutput | ||
); | ||
|
||
cy.get("[data-cy=options] > input[name=showIgnored]").uncheck(); | ||
cy.get("[data-cy=result-output] > label").should( | ||
"have.text", | ||
"Files to Copy" | ||
); | ||
cy.get("[data-cy=result-output] > textarea").should( | ||
"have.text", | ||
expectedCopyFilesOutput | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/// <reference types="cypress" /> | ||
// *********************************************** | ||
// This example commands.ts shows you how to | ||
// create various custom commands and overwrite | ||
// existing commands. | ||
// | ||
// For more comprehensive examples of custom | ||
// commands please read more here: | ||
// https://on.cypress.io/custom-commands | ||
// *********************************************** | ||
// | ||
// | ||
// -- This is a parent command -- | ||
// Cypress.Commands.add('login', (email, password) => { ... }) | ||
// | ||
// | ||
// -- This is a child command -- | ||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This is a dual command -- | ||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) | ||
// | ||
// | ||
// -- This will overwrite an existing command -- | ||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) | ||
// | ||
// declare global { | ||
// namespace Cypress { | ||
// interface Chainable { | ||
// login(email: string, password: string): Chainable<void> | ||
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element> | ||
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element> | ||
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element> | ||
// } | ||
// } | ||
// } |
Oops, something went wrong.