-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1274 from guardian/rk/e2e-cypress-okta
OAuth migration | Add E2E tests for OAuth authentication
- Loading branch information
Showing
31 changed files
with
535 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
name: manage-frontend cypress (E2E) | ||
on: | ||
pull_request: | ||
branches: | ||
- main | ||
workflow_dispatch: | ||
|
||
jobs: | ||
cypress: | ||
name: Manage-frontend Cypress (E2E) | ||
runs-on: ubuntu-latest | ||
|
||
permissions: | ||
id-token: write | ||
contents: read | ||
|
||
steps: | ||
- uses: aws-actions/configure-aws-credentials@v2 | ||
with: | ||
role-to-assume: ${{ secrets.MANAGE_FRONTEND_IAM_ROLE }} | ||
aws-region: eu-west-1 | ||
|
||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
cache: yarn | ||
|
||
- name: Setup OS, Nginx, and Certs | ||
run: | | ||
sudo apt-get update -y | ||
sudo apt-get install -y libnss3-tools | ||
sudo service nginx restart | ||
wget -q https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64 | ||
wget -q https://github.com/guardian/dev-nginx/releases/latest/download/dev-nginx.tar.gz | ||
sudo cp mkcert-v1.4.3-linux-amd64 /usr/local/bin/mkcert | ||
sudo chmod +x /usr/local/bin/mkcert | ||
sudo mkdir -p /usr/local/bin/dev-nginx | ||
sudo tar -xzf dev-nginx.tar.gz -C /usr/local | ||
sudo chmod +x /usr/local/bin/dev-nginx | ||
sudo dev-nginx setup-cert "profile.thegulocal.com" | ||
sudo dev-nginx setup-cert "manage.thegulocal.com" | ||
sudo dev-nginx setup-cert "members-data-api.thegulocal.com" | ||
sudo cp ./cypress/cypress-nginx.conf /etc/nginx/nginx.conf | ||
sudo dev-nginx restart-nginx | ||
- name: Cypress run | ||
uses: cypress-io/github-action@v6 | ||
env: | ||
CYPRESS_IDAPI_CLIENT_ACCESS_TOKEN: ${{ secrets.IDAPI_CLIENT_ACCESS_TOKEN }} | ||
# This env variable prevents Node from rejecting self-signed TLS certificates. It's | ||
# required for the Cypress tests to run as we're unable to verify the created certs. | ||
# See: https://nodejs.org/api/cli.html#node_tls_reject_unauthorizedvalue | ||
NODE_TLS_REJECT_UNAUTHORIZED: 0 | ||
with: | ||
start: yarn cypress:e2e:server | ||
wait-on: 'https://manage.thegulocal.com' | ||
wait-on-timeout: 30 | ||
quiet: true | ||
browser: chrome | ||
spec: cypress/tests/e2e/*.cy.ts | ||
|
||
- uses: actions/upload-artifact@v3 | ||
if: failure() | ||
with: | ||
name: cypress-screenshots | ||
path: cypress/screenshots |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,3 +28,4 @@ manage-frontend.zip | |
test-report.xml | ||
|
||
cypress/screenshots | ||
cypress.env.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# NGINX Conf file used by Cypress-Nginx Github actions | ||
# so we can run cypress tests against the local nginx server | ||
# with a ssl cert set on the domain | ||
|
||
#user nobody; | ||
worker_processes 1; | ||
|
||
events { | ||
worker_connections 1024; | ||
} | ||
|
||
http { | ||
include mime.types; | ||
default_type application/octet-stream; | ||
|
||
sendfile on; | ||
|
||
# Set to 5 seconds longer than 60 seconds (pretty sure this is a magic numnber). | ||
# This should help prevent timeouts in Cypress requests inside Github Actions. | ||
keepalive_timeout 65; | ||
|
||
# fixes issues for large response headers | ||
proxy_buffer_size 128k; | ||
proxy_buffers 4 256k; | ||
proxy_busy_buffers_size 256k; | ||
|
||
|
||
# manage.thegulocal.com | ||
# ====================== | ||
server { | ||
listen 443 ssl; | ||
server_name manage.thegulocal.com; | ||
proxy_http_version 1.1; # this is essential for chunked responses to work | ||
|
||
ssl_certificate manage.thegulocal.com.crt; | ||
ssl_certificate_key manage.thegulocal.com.key; | ||
ssl_session_timeout 5m; | ||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | ||
ssl_ciphers HIGH:!aNULL:!MD5; | ||
ssl_prefer_server_ciphers on; | ||
|
||
location / { | ||
proxy_pass http://localhost:9234/; | ||
proxy_set_header Host $http_host; | ||
proxy_http_version 1.1; | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection "Upgrade"; | ||
} | ||
} | ||
|
||
# members-data-api.thegulocal.com | ||
# ====================== | ||
server { | ||
listen 443 ssl; | ||
server_name members-data-api.thegulocal.com; | ||
proxy_http_version 1.1; # this is essential for chunked responses to work | ||
|
||
ssl_certificate members-data-api.thegulocal.com.crt; | ||
ssl_certificate_key members-data-api.thegulocal.com.key; | ||
ssl_session_timeout 5m; | ||
ssl_protocols TLSv1.2 TLSv1.3; | ||
ssl_ciphers HIGH:!aNULL:!MD5; | ||
ssl_prefer_server_ciphers on; | ||
|
||
location / { | ||
proxy_pass https://members-data-api.code.dev-theguardian.com; | ||
proxy_next_upstream error timeout http_404 non_idempotent; | ||
proxy_set_header "X-Forwarded-Proto" "https"; | ||
proxy_set_header Host members-data-api.code.dev-theguardian.com; | ||
proxy_set_header Accept-Encoding ""; | ||
proxy_hide_header Content-Security-Policy; | ||
|
||
proxy_cookie_domain members-data-api.code.dev-theguardian.com members-data-api.thegulocal.com; | ||
proxy_cookie_domain .code.dev-theguardian.com .thegulocal.com; | ||
|
||
sub_filter_types application/json; | ||
sub_filter_once off; | ||
sub_filter 'members-data-api.code.dev-theguardian.com' 'members-data-api.thegulocal.com'; | ||
} | ||
} | ||
|
||
|
||
# profile.thegulocal.com | ||
# ====================== | ||
server { | ||
listen 443 ssl; | ||
server_name profile.thegulocal.com; | ||
proxy_http_version 1.1; # this is essential for chunked responses to work | ||
|
||
ssl_certificate profile.thegulocal.com.crt; | ||
ssl_certificate_key profile.thegulocal.com.key; | ||
ssl_session_timeout 5m; | ||
ssl_protocols TLSv1.2 TLSv1.3; | ||
ssl_ciphers HIGH:!aNULL:!MD5; | ||
ssl_prefer_server_ciphers on; | ||
|
||
# dummy location header for the API | ||
proxy_set_header X-GU-ID-Geolocation ip:$remote_addr,country:GB,city:Leeds; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
|
||
location / { | ||
proxy_pass https://profile.code.dev-theguardian.com; | ||
proxy_next_upstream error timeout http_404 non_idempotent; | ||
proxy_set_header "X-Forwarded-Proto" "https"; | ||
proxy_set_header "X-GU-Okta-Env" "profile.code.dev-theguardian.com"; | ||
proxy_set_header Host profile.code.dev-theguardian.com; | ||
proxy_set_header Accept-Encoding ""; | ||
proxy_hide_header Content-Security-Policy; | ||
|
||
proxy_cookie_domain profile.code.dev-theguardian.com profile.thegulocal.com; | ||
proxy_cookie_domain .code.dev-theguardian.com .thegulocal.com; | ||
|
||
sub_filter_types application/json; | ||
sub_filter_once off; | ||
sub_filter 'profile.code.dev-theguardian.com' 'profile.thegulocal.com'; | ||
|
||
###### | ||
# remove `sid` cookie in requests to Gateway | ||
# save original "Cookie" header value | ||
set $altered_cookie $http_cookie; | ||
# check if the "sid" cookie is present | ||
# From: https://stackoverflow.com/a/67627604 | ||
if ($http_cookie ~ '(.*)(^|;\s)sid=("[^"]*"|[^\s]*[^;]?)(\2|$|;$)(?:;\s)?(.*)') { | ||
# cut "sid" cookie from the string | ||
set $altered_cookie $1$4$5; | ||
} | ||
# hide original "Cookie" header | ||
proxy_hide_header Cookie; | ||
# set "Cookie" header to the new value | ||
proxy_set_header Cookie $altered_cookie; | ||
###### | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Non-mocked sign-in with Gateway using Okta | ||
*/ | ||
|
||
export const signInOkta = () => { | ||
// When this function runs, the browser will already be showing the Gateway sign-in page | ||
// because MMA will have redirected to it when it loads the first page of the test. | ||
cy.setCookie('gu-cmp-disabled', 'true', { | ||
domain: '.thegulocal.com', | ||
}); | ||
|
||
// Necessary otherwise we get a 502 error back from MMA for some reason, perhaps a race condition? | ||
// TODO: Make this not suck | ||
cy.wait(1000); | ||
|
||
cy.visit('/'); | ||
cy.createTestUser({ | ||
isUserEmailValidated: true, | ||
})?.then(({ emailAddress, finalPassword }) => { | ||
cy.get('input[name=email]').type(emailAddress); | ||
cy.get('input[name=password]').type(finalPassword); | ||
cy.get('[data-cy="main-form-submit-button"]').click(); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { signInOkta } from '../../lib/signInOkta'; | ||
|
||
describe('E2E with Okta', () => { | ||
beforeEach(() => { | ||
Cypress.config('defaultCommandTimeout', 30_000); | ||
|
||
cy.clearAllCookies(); | ||
signInOkta(); | ||
cy.get('h1').should('contain', 'Account overview'); | ||
}); | ||
|
||
context('account overview tab', () => { | ||
it('should contain an email address', () => { | ||
cy.findByText('Email address'); | ||
}); | ||
}); | ||
|
||
context('profile tab', () => { | ||
it('should contain a username', () => { | ||
cy.visit('/public-settings'); | ||
cy.findByText('Username'); | ||
}); | ||
}); | ||
|
||
context('emails tab', () => { | ||
it('should allow the user to update their email preferences', () => { | ||
cy.visit('/email-prefs'); | ||
cy.findByText('Guardian products and support').click(); | ||
cy.visit('/email-prefs'); | ||
cy.findByText('Guardian products and support') | ||
.parents('div') | ||
.get('input[type="checkbox"]') | ||
.should('be.checked'); | ||
}); | ||
|
||
it('should allow the user to unsubscribe from all emails', () => { | ||
cy.visit('/email-prefs'); | ||
cy.findByText('Unsubscribe from all emails').click(); | ||
cy.visit('/email-prefs'); | ||
cy.get('input[type="checkbox"]').should('not.be.checked'); | ||
}); | ||
}); | ||
|
||
context('settings tab', () => { | ||
it('should allow the user to update their personal information', () => { | ||
cy.visit('/account-settings'); | ||
cy.findByLabelText('First Name').clear(); | ||
cy.findByLabelText('Last Name').clear(); | ||
cy.findByLabelText('First Name').type('Test'); | ||
cy.findByLabelText('Last Name').type('User'); | ||
cy.findByText('Save changes').click(); | ||
cy.visit('/account-settings'); | ||
cy.findByLabelText('First Name').should('have.value', 'Test'); | ||
cy.findByLabelText('Last Name').should('have.value', 'User'); | ||
}); | ||
}); | ||
|
||
context('help tab', () => { | ||
it('should allow the user to submit the help centre contact form', () => { | ||
cy.visit('/help'); | ||
cy.findByText( | ||
'If you still can’t find what you need and want to contact us, check', | ||
) | ||
.parent() | ||
.findByText('here') | ||
.click(); | ||
cy.findByText('Take me to the form').click(); | ||
cy.findByText('Begin form').click(); | ||
cy.findByText('Continue to step 2').click(); | ||
cy.findByLabelText('Full Name').type('Test'); | ||
cy.get('textarea[name="message"]').type('Problem details'); | ||
cy.solveGoogleReCAPTCHA(); | ||
cy.wait(1000); | ||
cy.findByText('Submit').click(); | ||
cy.findByText('Thank you for contacting us'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.