-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: cypress testing #17
Changes from all commits
06f4779
c334244
d928c87
4632740
e973e75
11e9cc7
b55eb7f
8a87dce
9619b38
8706083
247466f
7d37f7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
SUPABASE_URL= | ||
SUPABASE_ANON_KEY= | ||
SUPABASE_ANON_KEY= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: Run Cypress testing suite | ||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- development | ||
pull_request: | ||
|
||
jobs: | ||
cypress-run: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20.10.0 | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
- name: Cypress run | ||
uses: cypress-io/github-action@v6 | ||
with: | ||
build: yarn run build | ||
start: yarn start | ||
env: | ||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
# Values are set because the code requires them, but they are not actually used. | ||
SUPABASE_URL: "https://wfzpewmlyiozupulbuur.supabase.co" | ||
SUPABASE_ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6IndmenBld21seWlvenVwdWxidXVyIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTU2NzQzMzksImV4cCI6MjAxMTI1MDMzOX0.SKIL3Q0NOBaMehH0ekFspwgcu3afp3Dl9EDzPqs1nKs" | ||
- uses: actions/upload-artifact@v4 | ||
if: failure() | ||
with: | ||
name: cypress-screenshots | ||
path: cypress/screenshots | ||
if-no-files-found: ignore | ||
- uses: actions/upload-artifact@v4 | ||
if: failure() | ||
with: | ||
name: cypress-videos | ||
path: cypress/videos | ||
if-no-files-found: ignore |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,4 +7,6 @@ node_modules | |
.pnp.cjs | ||
.pnp.loader.mjs | ||
static/dist | ||
.env | ||
.env | ||
|
||
cypress/screenshots |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { defineConfig } from "cypress"; | ||
|
||
export default defineConfig({ | ||
e2e: { | ||
setupNodeEvents() { | ||
// implement node event listeners here | ||
}, | ||
|
||
baseUrl: "http://localhost:8080", | ||
experimentalStudio: true, | ||
}, | ||
viewportHeight: 900, | ||
viewportWidth: 1440, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
describe("DevPool", () => { | ||
let issue1: Record<string, unknown>; | ||
let issue2: Record<string, unknown>; | ||
let loginToken: Record<string, unknown>; | ||
let githubUser: Record<string, unknown>; | ||
before(() => { | ||
cy.fixture("issue-1.json").then((content) => { | ||
issue1 = content; | ||
}); | ||
cy.fixture("issue-2.json").then((content) => { | ||
issue2 = content; | ||
}); | ||
cy.fixture("user-token.json").then((content) => { | ||
loginToken = content; | ||
}); | ||
cy.fixture("user-github.json").then((content) => { | ||
githubUser = content; | ||
}); | ||
cy.intercept("https://api.github.com/repos/*/*/issues/**", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: issue1, | ||
}); | ||
}).as("getIssueDetails"); | ||
cy.intercept("https://api.github.com/orgs/*", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: issue1, | ||
}); | ||
}).as("orgs"); | ||
}); | ||
|
||
beforeEach(() => { | ||
// Very important to make sure we don't store data between tests | ||
cy.clearLocalStorage(); | ||
}); | ||
|
||
it.only("Main page displays issues", () => { | ||
// Should display one new task | ||
cy.log("Should display one new task"); | ||
cy.intercept("https://api.github.com/repos/*/*/issues**", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: [issue1], | ||
}); | ||
}).as("getIssues"); | ||
cy.visit("/"); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 1); | ||
cy.get("#issues-container > :nth-child(1)").should("have.class", "new-task"); | ||
|
||
// needed to make sure data is written to the local storage | ||
cy.wait(3000); | ||
|
||
// Should display still one old task | ||
cy.log("Should display still one old task"); | ||
cy.intercept("https://api.github.com/repos/*/*/issues**", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: [issue1, issue2], | ||
}); | ||
}).as("getIssues"); | ||
cy.visit("/"); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 1); | ||
cy.get("#issues-container > :nth-child(1)").should("not.have.class", "new-task"); | ||
|
||
// needed to make sure data is written to the local storage | ||
cy.wait(3000); | ||
|
||
cy.log("Should display two new tasks"); | ||
cy.clock(Date.now() + 95000000); | ||
cy.visit("/"); | ||
const fakeNow = new Date("2022-04-10"); | ||
// Needed due to a bug | ||
cy.clock(fakeNow).then((clock) => { | ||
// @ts-expect-error https://github.com/cypress-io/cypress/issues/7577 | ||
return clock.bind(window); | ||
}); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
}); | ||
|
||
it("Display a message on rate limited", () => { | ||
cy.intercept("https://api.github.com/repos/*/*/issues**", (req) => { | ||
req.reply({ | ||
statusCode: 403, | ||
}); | ||
}).as("getIssues"); | ||
cy.visit("/"); | ||
cy.get(".preview-header").should("exist"); | ||
}); | ||
|
||
it("Items can be sorted", () => { | ||
cy.intercept("https://api.github.com/repos/*/*/issues**", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: [issue1, issue2], | ||
}); | ||
}).as("getIssues"); | ||
cy.visit("/"); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="price"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="price"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="time"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="time"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="priority"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="priority"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="activity"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get('[for="activity"]').click(); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
cy.get("#filter").type("draft"); | ||
cy.get('div[id="issues-container"]').children().should("have.length", 2); | ||
}); | ||
|
||
it("User can log in", () => { | ||
cy.intercept("https://api.github.com/repos/*/*/issues**", (req) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are intercepting everything doesn't that kill the point of the test? Why don't we do real end-to-end tests? What if Supabase is broken and we can't oauth etc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we don't develop the other end (eg the backend) I didn't think it was relevant to test it. If GitHub backend breaks there is nothing we can do. The proper way to handle that would be to have BE error test cases, and to have a health check running on the production instance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay sounds smart I'm in. You can file some issues for this with sufficient details so we can get around to it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean an issue mentioning the creation of e2e testing with the real endpoint correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The proper way as you say |
||
req.reply({ | ||
statusCode: 200, | ||
body: [issue1, issue2], | ||
}); | ||
}).as("getIssues"); | ||
cy.intercept("https://api.github.com/user", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
body: githubUser, | ||
}); | ||
}).as("getUser"); | ||
cy.intercept("https://iyybhhiflwbsjopsgaow.supabase.co/auth/v1/authorize?provider=github", (req) => { | ||
req.reply({ | ||
statusCode: 200, | ||
}); | ||
// Simulate login token | ||
window.localStorage.setItem("sb-wfzpewmlyiozupulbuur-auth-token", JSON.stringify(loginToken)); | ||
0x4007 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}).as("githubLogin"); | ||
cy.visit("/"); | ||
cy.get("#github-login-button").click(); | ||
// Manually come back to home page after "login" | ||
cy.visit("/"); | ||
cy.get("#authenticated").should("exist"); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
{ | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085", | ||
"repository_url": "https://api.github.com/repos/ubiquity/devpool-directory", | ||
"labels_url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085/labels{/name}", | ||
"comments_url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085/comments", | ||
"events_url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085/events", | ||
"html_url": "https://github.com/ubiquity/devpool-directory/issues/1085", | ||
"id": 2152486458, | ||
"node_id": "I_kwDOJWyCVM6ATFY6", | ||
"number": 1085, | ||
"title": "Secure Secrets for Generalized Continuous Deploys", | ||
"user": { | ||
"login": "ubiquibot[bot]", | ||
"id": 113181824, | ||
"node_id": "BOT_kgDOBr8EgA", | ||
"avatar_url": "https://avatars.githubusercontent.com/in/236521?v=4", | ||
"gravatar_id": "", | ||
"url": "https://api.github.com/users/ubiquibot%5Bbot%5D", | ||
"html_url": "https://github.com/apps/ubiquibot", | ||
"followers_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/followers", | ||
"following_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/following{/other_user}", | ||
"gists_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/gists{/gist_id}", | ||
"starred_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/starred{/owner}{/repo}", | ||
"subscriptions_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/subscriptions", | ||
"organizations_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/orgs", | ||
"repos_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/repos", | ||
"events_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/events{/privacy}", | ||
"received_events_url": "https://api.github.com/users/ubiquibot%5Bbot%5D/received_events", | ||
"type": "Bot", | ||
"site_admin": false | ||
}, | ||
"labels": [ | ||
{ | ||
"id": 5389720203, | ||
"node_id": "LA_kwDOJWyCVM8AAAABQUCaiw", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/Time:%20%3C1%20Day", | ||
"name": "Time: <1 Day", | ||
"color": "ededed", | ||
"default": false, | ||
"description": null | ||
}, | ||
{ | ||
"id": 5390246739, | ||
"node_id": "LA_kwDOJWyCVM8AAAABQUijUw", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/Pricing:%20600%20USD", | ||
"name": "Pricing: 600 USD", | ||
"color": "ededed", | ||
"default": false, | ||
"description": null | ||
}, | ||
{ | ||
"id": 5639152271, | ||
"node_id": "LA_kwDOJWyCVM8AAAABUB6ijw", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/Unavailable", | ||
"name": "Unavailable", | ||
"color": "ededed", | ||
"default": false, | ||
"description": "" | ||
}, | ||
{ | ||
"id": 5906091134, | ||
"node_id": "LA_kwDOJWyCVM8AAAABYAfMfg", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/Priority:%203%20(High)", | ||
"name": "Priority: 3 (High)", | ||
"color": "ededed", | ||
"default": false, | ||
"description": null | ||
}, | ||
{ | ||
"id": 6607857261, | ||
"node_id": "LA_kwDOJWyCVM8AAAABidvmbQ", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/Partner:%20ubiquity/cloudflare-deploy-action", | ||
"name": "Partner: ubiquity/cloudflare-deploy-action", | ||
"color": "ededed", | ||
"default": false, | ||
"description": null | ||
}, | ||
{ | ||
"id": 6607857262, | ||
"node_id": "LA_kwDOJWyCVM8AAAABidvmbg", | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/labels/id:%20I_kwDOLGaFrM6ATBS4", | ||
"name": "id: I_kwDOLGaFrM6ATBS4", | ||
"color": "ededed", | ||
"default": false, | ||
"description": null | ||
} | ||
], | ||
"state": "open", | ||
"locked": false, | ||
"assignee": null, | ||
"assignees": [], | ||
"milestone": null, | ||
"comments": 0, | ||
"created_at": "2024-02-24T21:18:55Z", | ||
"updated_at": "2024-02-25T06:40:46Z", | ||
"closed_at": null, | ||
"author_association": "CONTRIBUTOR", | ||
"active_lock_reason": null, | ||
"body": "https://github.com/ubiquity/cloudflare-deploy-action/issues/1", | ||
"reactions": { | ||
"url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085/reactions", | ||
"total_count": 0, | ||
"+1": 0, | ||
"-1": 0, | ||
"laugh": 0, | ||
"hooray": 0, | ||
"confused": 0, | ||
"heart": 0, | ||
"rocket": 0, | ||
"eyes": 0 | ||
}, | ||
"timeline_url": "https://api.github.com/repos/ubiquity/devpool-directory/issues/1085/timeline", | ||
"performed_via_github_app": null, | ||
"state_reason": null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try setting all the correct types by importing them
Check this example https://github.com/ubiquity/github-labels-processor/blob/5f3921da1fa944d340cd375c3dfc4503531ebee5/src/github-types.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do. I didn't bother because they are populated from a string, so type checking is not relevant as I don't manipulate them. Will change it