Is it possible to update React context via Cypress?
Asked Answered
A

1

9

I am using Cypress for integration testing (not for unit testing / component testing) and working with application that has authentication logic depending on the presence of a security token in the application state - in one of the context used (created with react-tracked library). Without it - it is impossible to interact with the application. From what I could see Cypress is not suitable for testing of a remote authentication process (like via Azure AD), that's why I need to "pre-authenticate" the application in the beginning of each test by injecting the security token into the context. I saw examples of how to gain direct access to the Redux store:

const store = createStore(reducer)

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

// expose store when run in Cypress
if (window.Cypress) {
  window.store = store
}

(https://www.cypress.io/blog/2018/11/14/testing-redux-store/ — actually I'm not too sure if it would be even possible to update the store)

I couldn't find a similar solution for react context. Storing token in a cookie or local storage seems to be too risky. Changing a testing framework (Playwright seems to be a good candidate for us) would be a pain. Another option would be to create a special, hidden input in the application, to enter the token — but isn't there any better way?

Akimbo answered 25/5, 2021 at 12:58 Comment(0)
C
-1
Cypress.Commands.add("token", () => {
  let access_token = "";
  cy.request({
    method: "POST",
    url: "/auth/realms/cmem/protocol/openid-connect/token",
    form: true,
    body: {
      client_id: Cypress.env("service_account_client_id"),
      client_secret: Cypress.env("service_account_client_secret"),
      grant_type: Cypress.env("service_account_grant_type"),
    },
  }).then((response) => {
    access_token = response.body.access_token;
    window.localStorage.setItem("ACCESS_TOKEN", access_token);
  });
});

function getAccessToken() {
  return window.localStorage.getItem("ACCESS_TOKEN");
}
Cypress.Commands.add("dropAllGraphs", () => {
  cy.request({
    method: "POST",
    url: "https:google.com",
    headers: { authorization: "Bearer " + getAccessToken() },
    failOnStatusCode: false,
  }).then((response) => {
    const status = response.status;
    if (status == 401) {
      cy.token();
      cy.dropAllGraphs();
    } else if (status == 503) {
      cy.dropAllGraphs();
    }
  });
});

I think is it useful for you

Cinderella answered 24/11, 2022 at 16:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.