Closed qhu1234 closed 9 months ago
OMG I been trying to figure it out for 3 days and finally figured out.
I read the document here: https://docs.cypress.io/api/cypress-api/custom-commands#Command-Logging it says"
To support sideEffects:false, you can wrap the Cypress commands in a function that will be imported by the support file."
I don't have sideEffects:false
defined in my package.json file but I tried to move my loginByOktaApi
custom function in cypress-> support -> command.ts and wrap it with export function registerCommands() {...}
and in my e2e.ts I pasted these 2 lines
import { registerCommands } from './commands' registerCommands()
and it finally registered the custom function.
I'm glad you figured this out, @qhu1234 ! Closing this issue as resolved.
I followed the entire tutorial to try to make the okta authentication from here: https://docs.cypress.io/guides/end-to-end-testing/okta-authentication. And I also cloned this cypress-realworld-app to follow the exact same steps of how it sets up the okta.ts and the unit test file. I'd say the tutorial has the steps that are way different than how the repo sets up. The tutorial doesn't mention that you need to create a file named global.d.ts and add custom functions in there and some other places you need to make it work.
So here's what i have done:
const loginToOkta = (username: string, password: string) => { Cypress.log({ displayName: "OKTA LOGIN", message: [
🔐 Authenticating | ${username}
], autoEnd: false, });cy.visit("/"); cy.origin(Cypress.env("okta_domain"), { args: { username, password } }, ({ username, password }) => { cy.get('input[name="identifier"]').type(username); cy.get('input[name="credentials.passcode"]').type(password, { log: false, }); cy.get('[type="submit"]').click(); });
cy.get('[data-test="sidenav-username"]').should("contain", username); }; Cypress.Commands.add("loginByOkta", (username: string, password: string) => { cy.session(
okta-${username}
, () => { return loginToOkta(username, password); }, { validate() { cy.visit("/"); cy.get('[data-test="sidenav-username"]').should("contain", username); }, }, ); }); // Okta Cypress.Commands.add("loginByOktaApi", (username, password) => { const optionsSessionToken = { method: 'POST', url: 'https://newscorp.okta.com/api/v1/authn', body: { username: username, password: password, options: { warnBeforePasswordExpired: 'true' } } };//first cy.request you need to get a OKTA session token cy.request(optionsSessionToken).then(resp => { const sessionToken = resp.body.sessionToken; //once you have a token, you need to hit okta authorize URL with client ID and redirect URL. //it will be a very long string with different params. Add a session token at the end of the string as parameter cy.request({ method: 'GET', url: 'https://your_company_link_to_authorize.com/oauth2/default/v1/authorize?client_id=11111111&redirect_uri=http://localhost:4200/callback&response_type=id_token token&OTHER PARAMS PARAMS PARAMS&sessionToken=' + sessionToken, form: true, followRedirect: false }).then(respWithToken => { const url = respWithToken.redirectedToUrl; if (url) { const token = (url as string) .substring(url.indexOf('access_token')) .split('=')[1] .split('&')[0]; cy.wrap(token).as('token'); //last step is to visit the redirecturl and then visit homepage of the app cy.visit(url).then(() => { cy.visit('/'); }); } }); }); }); `
cypress.config.ts
to change the spec file to read from tests folder instead of the defaulte2e
folder: `import { applicationConfig } from "../../src/config"; import { Config } from "../../src/config/common";describe("ETRD page testing", () => { let config: Config = applicationConfig; beforeEach(function() { cy.loginByOktaApi(Cypress.env("okta_username"), Cypress.env("okta_password")); //cy.loginByOkta(Cypress.env("okta_username"), Cypress.env("okta_password")); cy.visit("/"); });
it("Visits ETRD main page to check if content loads", () => { cy.visit(config.externalServices.etrdDevPortal.href); }); }); `
declare namespace Cypress { interface Chainable { /**
Window object with additional properties used during test. */ window(options?: Partial<Loggable & Timeoutable>): Chainable;
/**
Logs-in user by using Okta API request */ loginByOktaApi(username: string, password?: string): Chainable;
/**
// Augment the Cypress namespace to include type definitions for // your custom command. // Alternatively, can be defined in cypress/support/component.d.ts // with a at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}
In this cypress-realworld-app, the only 3 places I can find
loginByOktaApior
loginByOktaare
global.t.ds,
okta.tsand
okta.spec.ts`When I run yarn cypress:open and navigate to the spec testing page it's still saying cy.loginByOktaApi is not a function.
It's already taking me 2 days to make the function work what else do I miss to make it work? I use VS code, MacOS ventura and just upgraded to Sonoma. What else do I need to set up to have the application recognize the custom function?