Skip to content

Commit

Permalink
fix: express e2e tests for new account experience (#2708)
Browse files Browse the repository at this point in the history
  • Loading branch information
Benehiko authored Oct 13, 2022
1 parent 0c2efa2 commit 84ea0cf
Show file tree
Hide file tree
Showing 22 changed files with 272 additions and 70 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ schema.sql
heap_profiler/
goroutine_dump/
inflight_trace_dump/

.vscode
15 changes: 11 additions & 4 deletions test/e2e/cypress/integration/profiles/email/error/ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,17 @@ describe("Handling self-service error flows", () => {
failOnStatusCode: false,
})

cy.get(`${appPrefix(app)}code`).should(
"contain.text",
"This is a stub error.",
)
if (app === "express") {
cy.get(`${appPrefix(app)} [data-testid="ui/error/message"]`).should(
"contain.text",
"This is a stub error.",
)
} else {
cy.get(`${appPrefix(app)}code`).should(
"contain.text",
"This is a stub error.",
)
}
})
})
})
Expand Down
12 changes: 11 additions & 1 deletion test/e2e/cypress/integration/profiles/email/login/error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ describe("Basic email profile with failing login flows", () => {

describe("shows validation errors when invalid signup data is used", () => {
it("should show an error when the identifier is missing", () => {
// the browser will prevent the form from submitting if the fields are empty since they are required
// here we just remove the required attribute to make the form submit
cy.removeAttribute(
['input[name="identifier"]', 'input[name="password"]'],
"required",
)
cy.submitPasswordForm()
cy.get('*[data-testid="ui/message/4000002"]').should(
"contain.text",
Expand All @@ -61,11 +67,15 @@ describe("Basic email profile with failing login flows", () => {
.type(identity)
.should("have.value", identity)

// the browser will prevent the form from submitting if the fields are empty since they are required
// here we just remove the required attribute to make the form submit
cy.removeAttribute(['input[name="password"]'], "required")

cy.submitPasswordForm()
cy.get('*[data-testid^="ui/message/"]')
.invoke("text")
.then((text) => {
expect(text).to.be.oneOf([
expect(text.trim()).to.be.oneOf([
"length must be >= 1, but got 0",
"Property password is missing.",
])
Expand Down
14 changes: 10 additions & 4 deletions test/e2e/cypress/integration/profiles/email/logout/success.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ context("Testing logout flows", () => {
it("should sign out and be able to sign in again", () => {
cy.getSession()
cy.getCookie("ory_kratos_session").should("not.be.null")
cy.get(
`${appPrefix(app)} [data-testid="logout"]:not(.disabled)`,
).click()
if (app === "express") {
cy.get(
`${appPrefix(app)} [data-testid="logout"] a:not(.disabled)`,
).click()
} else {
cy.get(
`${appPrefix(app)} [data-testid="logout"]:not(.disabled)`,
).click()
}
cy.getCookie("ory_kratos_session").should("be.null")
cy.noSession()
cy.url().should("include", "/login")
cy.getCookie("ory_kratos_session").should("be.null")
})
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("Registration failures with email profile", () => {
const password = gen.password()

it("fails when CSRF cookies are missing", () => {
cy.get(`${appPrefix(app)}input[name="traits.website"]`).type(
cy.get(`${appPrefix(app)} input[name="traits.website"]`).type(
"https://www.ory.sh",
)
cy.get('input[name="traits.email"]')
Expand Down Expand Up @@ -82,11 +82,15 @@ describe("Registration failures with email profile", () => {
cy.get('input[name="traits.website"]').type("https://www.ory.sh")
cy.get('input[name="traits.email"]').type(identity)

// the browser will prevent the form from being submitted if the input field is required
// we should remove the required attribute to simulate the data not being sent
cy.removeAttribute(['input[name="password"]'], "required")

cy.submitPasswordForm()
cy.get('*[data-testid^="ui/message/"]')
.invoke("text")
.then((text) => {
expect(text).to.be.oneOf([
expect(text.trim()).to.be.oneOf([
"length must be >= 1, but got 0",
"Property password is missing.",
])
Expand All @@ -97,11 +101,15 @@ describe("Registration failures with email profile", () => {
cy.get('input[name="traits.website"]').type("https://www.ory.sh")
cy.get('input[name="password"]').type(password)

// the browser will prevent the form from being submitted if the input field is required
// we should remove the required attribute to simulate the data not being sent
cy.removeAttribute(['input[name="traits.email"]'], "required")

cy.submitPasswordForm()
cy.get('*[data-testid^="ui/message/"]')
.invoke("text")
.then((text) => {
expect(text).to.be.oneOf([
expect(text.trim()).to.be.oneOf([
'"" is not valid "email"length must be >= 3, but got 0',
"Property email is missing.",
])
Expand All @@ -110,7 +118,15 @@ describe("Registration failures with email profile", () => {

it("should show an error when the email is not an email", () => {
cy.get('input[name="traits.website"]').type("https://www.ory.sh")
cy.get('input[name="password"]').type("not-an-email")
cy.get('input[name="password"]').type(password)

// the browser will prevent the form from being submitted if the input data doesn't conform to the input field type
// in this case an invalid email will prevent the form from being submitted by the browser
// we should remove it to ensure kratos is validating the payload
cy.get('input[name="traits.email"]').then(($el) =>
$el.removeAttr("type"),
)
cy.get('input[name="traits.email"]').type("not-an-email")

cy.submitPasswordForm()
cy.get(
Expand All @@ -119,6 +135,17 @@ describe("Registration failures with email profile", () => {
})

it("should show a missing indicator if no fields are set", () => {
// the browser will prevent the form from being submitted if the input field is required
// we should remove the required attribute to simulate the data not being sent
cy.removeAttribute(
[
'input[name="traits.email"]',
'input[name="traits.website"]',
'input[name="password"]',
],
"required",
)

cy.submitPasswordForm()
cy.get(
'*[data-testid="ui/message/4000001"], *[data-testid="ui/message/4000002"]',
Expand All @@ -136,6 +163,13 @@ describe("Registration failures with email profile", () => {
})

it("should show an error when the website is too short", () => {
// the browser will prevent the form from being submitted if the input field is required
// we should remove the required attribute to simulate the data not being sent
cy.removeAttribute(
['input[name="traits.email"]', 'input[name="password"]'],
"required",
)

cy.get('input[name="traits.website"]').type("http://s")

cy.submitPasswordForm()
Expand All @@ -146,6 +180,12 @@ describe("Registration failures with email profile", () => {
})

it("should show an error when required params are missing", () => {
// the browser will prevent the form from being submitted if the input field is required
// we should remove it from the DOM entirely to simulate the data not being sent
cy.get('input[name="traits.website"]').then(($el) => $el.remove())
cy.get('input[name="traits.email"]').then(($el) => $el.remove())
cy.get('input[name="password"]').then(($el) => $el.remove())

cy.submitPasswordForm()
cy.get('*[data-testid^="ui/message"]').should(
"contain.text",
Expand All @@ -162,6 +202,17 @@ describe("Registration failures with email profile", () => {
})

it("should show an error when the age is too high", () => {
// the browser will prevent the form from being submitted if the input field is required
// we should remove the required attribute to simulate the data not being sent
cy.removeAttribute(
[
'input[name="traits.email"]',
'input[name="traits.website"]',
'input[name="password"]',
],
"required",
)

cy.get('input[name="traits.age"]').type("600")

cy.submitPasswordForm()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ context("Registration success with email profile", () => {
cy.get('[type="checkbox"][name="traits.tos"]').click({ force: true })

cy.submitPasswordForm()
if (app === "express") {
cy.get('a[href*="sessions"').click()
}
cy.get("pre").should("contain.text", email)

cy.getSession().should((session) => {
Expand All @@ -66,6 +69,9 @@ context("Registration success with email profile", () => {
cy.get('input[name="traits.website"]').type(website)

cy.submitPasswordForm()
if (app === "express") {
cy.get('a[href*="sessions"').click()
}
cy.get("pre").should("contain.text", email)

cy.getSession().should((session) => {
Expand Down Expand Up @@ -113,7 +119,7 @@ context("Registration success with email profile", () => {
const password = gen.password()
const website = "https://www.example.org/"

cy.get(appPrefix("express") + 'input[name="traits"]').should("not.exist")
cy.get(`${appPrefix("express")} input[name="traits"]`).should("not.exist")
cy.get('input[name="traits.email"]').type(email)
cy.get('input[name="traits.website').type(website)
cy.get('input[name="password"]').type(password)
Expand Down
14 changes: 12 additions & 2 deletions test/e2e/cypress/integration/profiles/email/settings/ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ context("Settings errors with email profile", () => {

describe("use ui elements", () => {
it("should use the json schema titles", () => {
cy.get(appPrefix(app) + 'a[href*="settings"]').click()
const settingsLink = appPrefix(app) + 'a[href*="settings"]'
if (app === "express") {
cy.get(settingsLink).should("have.attr", "target", "_blank")
cy.removeAttribute([settingsLink], "target")
}
cy.get(settingsLink).click()
cy.get('input[name="traits.email"]')
.parent()
.should("contain.text", "Your E-Mail")
Expand All @@ -49,7 +54,12 @@ context("Settings errors with email profile", () => {
})

it("clicks the settings link", () => {
cy.get('a[href*="settings"]').click()
const settingsLink = 'a[href*="settings"]'
if (app === "express") {
cy.get(settingsLink).should("have.attr", "target", "_blank")
cy.removeAttribute([settingsLink], "target")
}
cy.get(settingsLink).click()
cy.location("pathname").should("include", "settings")
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ context("Import Identities", () => {
})

cy.visit(express.login)
cy.triggerOidc({ url: express.login })
cy.triggerOidc("express")

cy.get("#username").clear().type(email)
cy.get("#remember").click()
Expand Down
1 change: 1 addition & 0 deletions test/e2e/cypress/integration/profiles/mfa/mix.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ context("2FA with various methods", () => {
cy.get('[name="totp_code"]').then(($e) => {
cy.wrap($e).type(authenticator.generate(secret))
})

cy.get('[name="method"][value="totp"]').click()
cy.location("pathname").should("not.include", "/login")

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/cypress/integration/profiles/mfa/totp.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ context("2FA lookup secrets", () => {
})
cy.get('*[name="method"][value="totp"]').click()
cy.location("pathname").should((loc) => {
expect(loc).to.oneOf(["/welcome", "/"])
expect(loc).to.oneOf(["/welcome", "/", "/sessions"])
})
cy.getSession({
expectAal: "aal2",
Expand Down
16 changes: 7 additions & 9 deletions test/e2e/cypress/integration/profiles/network/errors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("Registration failures with email profile", () => {
it("should not be able to register if we need a localhost schema", () => {
cy.setDefaultIdentitySchema("localhost")
cy.visit(express.registration, { failOnStatusCode: false })
cy.get(".code-box").should(
cy.get('[data-testid="code-box"]').should(
"contain.text",
"ip 127.0.0.1 is in the 127.0.0.0/8",
)
Expand All @@ -19,7 +19,7 @@ describe("Registration failures with email profile", () => {
it("should not be able to register if we schema has a local ref", () => {
cy.setDefaultIdentitySchema("ref")
cy.visit(express.registration, { failOnStatusCode: false })
cy.get(".code-box").should(
cy.get('[data-testid="code-box"]').should(
"contain.text",
"ip 192.168.178.1 is in the 192.168.0.0/16 range",
)
Expand All @@ -28,7 +28,7 @@ describe("Registration failures with email profile", () => {
it("should not be able to login because pre webhook uses local url", () => {
cy.setDefaultIdentitySchema("working")
cy.visit(express.login, { failOnStatusCode: false })
cy.get(".code-box").should(
cy.get('[data-testid="code-box"]').should(
"contain.text",
"ip 192.168.178.2 is in the 192.168.0.0/16 range",
)
Expand All @@ -37,13 +37,11 @@ describe("Registration failures with email profile", () => {
it("should not be able to verify because post webhook uses local jsonnet", () => {
cy.setDefaultIdentitySchema("working")
cy.visit(express.registration, { failOnStatusCode: false })
cy.get('[data-testid="node/input/traits.email"] input').type(gen.email())
cy.get('[data-testid="node/input/traits.website"] input').type(
"https://google.com/",
)
cy.get('[data-testid="node/input/password"] input').type(gen.password())
cy.get('input[name="traits.email"]').type(gen.email())
cy.get('input[name="traits.website"]').type("https://google.com/")
cy.get('input[name="password"]').type(gen.password())
cy.get('[type="submit"]').click()
cy.get(".code-box").should(
cy.get('[data-testid="code-box"]').should(
"contain.text",
"ip 192.168.178.3 is in the 192.168.0.0/16 range",
)
Expand Down
10 changes: 7 additions & 3 deletions test/e2e/cypress/integration/profiles/oidc/login/success.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,27 @@ context("Social Sign In Successes", () => {

it("should be able to sign up, sign out, and then sign in", () => {
const email = gen.email()
cy.registerOidc({ email, website, route: registration })
cy.registerOidc({ app, email, website, route: registration })
cy.logout()
cy.noSession()
cy.loginOidc({ url: login })
cy.loginOidc({ app, url: login })
})

it("should be able to sign up with redirects", () => {
const email = gen.email()
cy.registerOidc({
app,
email,
website,
route: registration + "?return_to=https://www.example.org/",
})
cy.location("href").should("eq", "https://www.example.org/")
cy.logout()
cy.noSession()
cy.loginOidc({ url: login + "?return_to=https://www.example.org/" })
cy.loginOidc({
app,
url: login + "?return_to=https://www.example.org/",
})
cy.location("href").should("eq", "https://www.example.org/")
})
})
Expand Down
12 changes: 10 additions & 2 deletions test/e2e/cypress/integration/profiles/oidc/logout/success.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ context("Social Sign Out Successes", () => {
beforeEach(() => {
cy.visit(base)
const email = gen.email()
cy.registerOidc({ email, website, route: registration })
cy.registerOidc({ app, email, website, route: registration })
})

it("should sign out and be able to sign in again", () => {
cy.get(`${appPrefix(app)} [data-testid="logout"]:not(disabled)`).click()
if (app === "express") {
cy.get(
`${appPrefix(app)} [data-testid="logout"] a:not(disabled)`,
).click()
} else {
cy.get(
`${appPrefix(app)} [data-testid="logout"]:not(disabled)`,
).click()
}
cy.noSession()
cy.url().should("include", "/login")
})
Expand Down
Loading

0 comments on commit 84ea0cf

Please sign in to comment.