Skip to content
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

Add Okta support to Cypress tests #12686

Closed
1 task done
mraible opened this issue Oct 8, 2020 · 8 comments · Fixed by #13611
Closed
1 task done

Add Okta support to Cypress tests #12686

mraible opened this issue Oct 8, 2020 · 8 comments · Fixed by #13611
Labels
area: feature request 💡 $$ bug-bounty $$ https://www.jhipster.tech/bug-bounties/ theme: tests $200 https://www.jhipster.tech/bug-bounties/
Milestone

Comments

@mraible
Copy link
Contributor

mraible commented Oct 8, 2020

Overview of the feature request

Our current Protractor tests support testing against Okta. Our Cypress tests should have the same ability. The major thing to make this happen is allowing E2E_USERNAME and E2E_PASSWORD to be read if they're set. Otherwise, default to admin/admin for Keycloak.

Motivation for or Use Case

I like to see if Okta works with the latest version of JHipster.

Related issues or PR

#12674

  • Checking this box is mandatory (this is just to show you read everything)
@mshima
Copy link
Member

mshima commented Oct 21, 2020

Rename:

  • keycloackLogout to oauth2Logout or something generic.
  • keycloackLogin to oauth2Login or something generic.

@mraible mraible added $$ bug-bounty $$ https://www.jhipster.tech/bug-bounties/ $200 https://www.jhipster.tech/bug-bounties/ labels Oct 21, 2020
@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity.
Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted.
We are accepting PRs 😃.
Comment or this will be closed in 7 days

@github-actions
Copy link
Contributor

This issue is stale because it has been open 30 days with no activity.
Our core developers tend to be more verbose on denying. If there is no negative comment, possibly this feature will be accepted.
We are accepting PRs 😃.
Comment or this will be closed in 7 days

@mraible
Copy link
Contributor Author

mraible commented Dec 29, 2020

Please keep this open as it's something I care about.

@mraible
Copy link
Contributor Author

mraible commented Jan 14, 2021

I tried this today and it still fails. Ideally, you could do like you can with Protractor:

export E2E_USERNAME=<okta.username>
export E2E_PASSWORD=<okta.password>
npm run e2e

@atomfrede
Copy link
Member

atomfrede commented Jan 16, 2021

I have maybe found and ugly workaround (will only work with chrome I think). Not sure we should further investigate that but it looks okaish to me as we don't need to interact with either keycloak or okta auth api directly cypress-io/cypress#944 (comment)

Possible workaround example with cookies: cypress-io/cypress#944 (comment)

@atomfrede
Copy link
Member

atomfrede commented Jan 18, 2021

@mraible Good news, I could make use of puppeteer to login into keycloak with the browser (headless or non headless) and use the resulting cookies inside the cypress tests. Basically following has changed:

plugins/index.tx:

  on('task', {
    login({ username, password }) {
      return (async () => {
        const browser = await puppeteer.launch({ 
          args: ['--no-sandbox', '--disable-setuid-sandbox'],
          devtools: true, 
          ignoreHTTPSErrors: true, 
          headless: true });
          
        const page = await browser.newPage();
   
        await page.goto('http://localhost:8080/oauth2/authorization/oidc', { // The app redirects to the login-page
          waitUntil: 'networkidle2' // Wait until login-page has been reached
        });
        
        await page.type('#username', username); // Insert username in form
        await page.type('#password', password); // Insert password
        await page.click('input[type="submit"]'); // Click login button

        await page.waitForNavigation({ waitUntil: 'networkidle2' }); // Wait until redirected back to the app
        
        const authCookies = await page.cookies();
        
        await browser.close(); // Close puppeteer
        return authCookies;
      })();
    },
    logout() {
      return (async () => {
      const browser = await puppeteer.launch({ ignoreHTTPSErrors: true });
      const page = await browser.newPage();
      await page.goto('http://localhost:8080/api/logout', { // The app redirects to the login-page
        waitUntil: 'networkidle2' // Wait until login-page has been reached
      });
      return true;
    })
    }
  });

custom cypress commands:

Cypress.Commands.add('oauthLogin', (username, password) => {
    cy.task('login', {username: username, password: password}).then(cookies => {
      cookies.forEach(c => {
        const name = c.name;
        const value = c.value;
        const options = {
          ...c
        }
        cy.setCookie(name, value, options);
      });
      cy.visit('/');
    });
  });

  Cypress.Commands.add('oauthLogout', (username, password) => {
    cy.task('logout').then(cookies => {
      cy.clearCookies();
    });
  });


declare global {
  namespace Cypress {
    interface Chainable<Subject> {
      oauthLogin(username: string, password: string): Cypress.Chainable;
      oauthLogout(): Cypress.Chainable;
    }
  }
}

// Convert this to a module instead of script (allows import/export)
export {};

and usage in the tests:

import {
  metricsPageHeadingSelector,
  healthPageHeadingSelector,
  logsPageHeadingSelector,
  configurationPageHeadingSelector,
} from '../../support/commands';

describe('/admin', () => {
  beforeEach(() => {
    cy.oauthLogin("admin", "admin");
  });

  afterEach(() => {
    cy.oauthLogout();
  });

  describe('/metrics', () => {
    it('should load the page', () => {
      cy.clickOnAdminMenuItem('metrics');
      cy.get(metricsPageHeadingSelector).should('be.visible');
    });
  });

});

So now we could basically overwrite the username/password again. There is some tweaking required for the username/password field as they have different ids on keycloak/okta but that should be easy at first glance.

BUT: As puppeteer only works with chrome/chromium we can't run the e2e tests e.g. with firefox or at least it requires chrome to do the login.

@mraible
Copy link
Contributor Author

mraible commented Jan 18, 2021

Nice @atomfrede! That looks pretty slick.

atomfrede added a commit to atomfrede/generator-jhipster that referenced this issue Jan 19, 2021
atomfrede added a commit to atomfrede/generator-jhipster that referenced this issue Jan 19, 2021
atomfrede added a commit to atomfrede/generator-jhipster that referenced this issue Jan 21, 2021
atomfrede added a commit that referenced this issue Jan 27, 2021
* support okta with cypress tests

closes #12686

* correctly guard oauth specific functions/utils

* append login/logout paths correctly to baseUrl

* use keycloak api and only pupeteer when using okta

* fix oauth2 data creation

* add missing keycloakLogin function

* Apply suggestions from code review

Co-authored-by: Marcelo Shima <marceloshima@gmail.com>

* correct identation

* replace deprecated waitFor with waitforSelector

Co-authored-by: Marcelo Shima <marceloshima@gmail.com>
@pascalgrimaud pascalgrimaud added this to the v7.0.0-beta.2 milestone Feb 20, 2021
coderguy-tech pushed a commit to coderguy-tech/generator-jhipster that referenced this issue Jun 1, 2021
* support okta with cypress tests

closes jhipster#12686

* correctly guard oauth specific functions/utils

* append login/logout paths correctly to baseUrl

* use keycloak api and only pupeteer when using okta

* fix oauth2 data creation

* add missing keycloakLogin function

* Apply suggestions from code review

Co-authored-by: Marcelo Shima <marceloshima@gmail.com>

* correct identation

* replace deprecated waitFor with waitforSelector

Co-authored-by: Marcelo Shima <marceloshima@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: feature request 💡 $$ bug-bounty $$ https://www.jhipster.tech/bug-bounties/ theme: tests $200 https://www.jhipster.tech/bug-bounties/
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants