Skip to content

Commit

Permalink
Merge pull request #138 from PagerDuty/release/0.8.3-beta.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gsreynolds authored Jul 5, 2023
2 parents 8ae8472 + 0a20b54 commit 94dfabb
Show file tree
Hide file tree
Showing 16 changed files with 259 additions and 245 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/cd-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ jobs:
node-version: '16.19.0'
- name: Install Yarn
run: npm install -g yarn
# https://github.com/actions/cache/blob/main/examples.md#node---yarn
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-modules-
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install project dependencies (via cache)
run: yarn --prefer-offline
- name: Build application bundle
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/lint-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ jobs:
- uses: actions/checkout@v2
- name: Install Yarn
run: npm install -g yarn
# https://github.com/actions/cache/blob/main/examples.md#node---yarn
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-modules-
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install project dependencies (via cache)
run: yarn --prefer-offline
- name: Run ESLint
Expand Down
123 changes: 57 additions & 66 deletions .github/workflows/test-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,61 @@ concurrency:
group: 'develop'

jobs:
build-id:
install:
runs-on: ubuntu-latest
outputs:
uuid: ${{ steps.uuid.outputs.value }}
steps:
- name: 'uuid'
id: uuid
run: echo "::set-output name=value::$GITHUB_SHA-$(date +"%s")"
- uses: actions/checkout@v3
- name: Install Yarn
run: npm install -g yarn
# https://github.com/actions/cache/blob/main/examples.md#node---yarn
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install project dependencies (via cache)
run: yarn --prefer-offline

jest:
needs: install
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Yarn
run: npm install -g yarn
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-modules-
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install project dependencies (via cache)
run: yarn --prefer-offline
- name: Run Jest Tests
run: yarn jest

cypress-run:
needs: build-id
needs: install
runs-on: ubuntu-latest
container:
image: cypress/browsers:node16.16.0-chrome107-ff107
options: --user 1001
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4, 5]
e2e:
- Incidents/incidents.spec.js
- Query/query.spec.js
- Search/search.spec.js
- Settings/settings.spec.js
- app.spec.js
env:
REACT_APP_PD_ENV: 'github-ci'
REACT_APP_PD_SUBDOMAIN_ALLOW_LIST: '*'
Expand All @@ -59,66 +75,41 @@ jobs:
REACT_APP_DD_SAMPLE_RATE: ${{ secrets.DD_SAMPLE_RATE }}
REACT_APP_DD_TRACK_INTERACTIONS: ${{ secrets.DD_TRACK_INTERACTIONS }}
REACT_APP_DD_DEFAULT_PRIVACY_LEVEL: ${{ secrets.DD_DEFAULT_PRIVACY_LEVEL }}
CYPRESS_API_URL: ${{ format('{0}:1234', secrets.CYPRESS_API_URL) }}
CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Cache Yarn Dependencies
uses: actions/cache@v2
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache
with:
path: |
~/.cache/Cypress
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-modules-
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install project dependencies (via cache)
run: yarn --prefer-offline
- name: Run Cypress Tests
run: |
Xvfb -screen 0 1920x1080x24 :99 & export DISPLAY=:99
yarn start &
npx wait-on http://localhost:3000 && \
npx cy2 run \
--group "e2e" \
--browser chrome \
--headless \
--parallel \
--record \
--key ${CYPRESS_RECORD_KEY} \
--ci-build-id ${{ needs.build-id.outputs.uuid }} && \
pkill Xvfb
# Below steps required to pass GitHub status as we are manually running Cypress
- name: Cypress tests ✅
if: ${{ success() }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
--header 'authorization: Bearer ${{ secrets.GH_TOKEN }}' \
--header 'content-type: application/json' \
--data '{
"context": "cypress-run",
"state": "success",
"description": "Cypress tests passed",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}'
- name: Cypress tests 🚨
if: ${{ failure() }}
run: |
curl --request POST \
--url https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
--header 'authorization: Bearer ${{ secrets.GH_TOKEN }}' \
--header 'content-type: application/json' \
--data '{
"context": "cypress-run",
"state": "failure",
"description": "Cypress tests failed",
"target_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}'
- name: Cypress run
# Uses the official Cypress GitHub action https://github.com/cypress-io/github-action
uses: cypress-io/github-action@v4
with:
# Starts web server for E2E tests - replace with your own server invocation
# https://docs.cypress.io/guides/continuous-integration/introduction#Boot-your-server
start: yarn start
wait-on: 'http://localhost:3000' # Waits for above
browser: chrome
# Records to Cypress Cloud
# https://docs.cypress.io/guides/cloud/projects#Set-up-a-project-to-record
record: true
# Specify Cypress test spec files in each matrix job to deterministically run tests in parallel
spec: cypress/e2e/${{ matrix.e2e }}
parallel: false # Don't use Cypress in-built parallelization
env:
# For recording and parallelization to work you must set your CYPRESS_RECORD_KEY
# in GitHub repo → Settings → Secrets → Actions
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# Creating a token https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ module.exports = defineConfig({
},
baseUrl: "http://localhost:3000/pd-live-react",
specPattern: "cypress/e2e/**/*.spec.{js,ts,jsx,tsx}",
// Cypress 12 introduces Test Isolation by default which breaks our current tests
// https://docs.cypress.io/guides/references/migration-guide#Test-Isolation
testIsolation: false
},

component: {
Expand Down
5 changes: 5 additions & 0 deletions cypress/e2e/Incidents/incidents.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
runResponsePlay,
checkActionAlertsModalContent,
checkIncidentCellContent,
checkNoIncidentsSelected,
// activateButton,
// deactivateButton,
priorityNames,
Expand All @@ -43,6 +44,10 @@ describe('Manage Open Incidents', { failFast: { enabled: false } }, () => {
waitForIncidentTable();
});

afterEach(() => {
checkNoIncidentsSelected();
});

it('Select all incidents', () => {
selectAllIncidents();
cy.get('.selected-incidents-badge').then(($el) => {
Expand Down
45 changes: 19 additions & 26 deletions cypress/e2e/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ describe('PagerDuty Live', () => {
});

it('Application indicates when the required ability is available on the account', () => {
cy.get('.status-beacon-ctr').trigger('mouseover');
cy.get('.status-beacon-connection').should('be.visible');
cy.get('.status-beacon-connection').contains('Connected', { timeout: 30000 });
cy.get('.status-beacon-ctr').realHover();
cy.get('[data-popper-placement="bottom"]').should('be.visible');
cy.get('[data-popper-placement="bottom"]').contains('Connected', { timeout: 30000 });
});

it('Application indicates when the required ability is missing/disabled on the account', () => {
Expand All @@ -67,23 +67,23 @@ describe('PagerDuty Live', () => {
cy.wait('@getAbilities', { timeout: 30000 });

// The mock response will render an error in the application
cy.get('.status-beacon-ctr').trigger('mouseover');
cy.get('.status-beacon-connection').should('be.visible');
cy.get('.status-beacon-connection').contains(
cy.get('.status-beacon-ctr').realHover();
cy.get('[data-popper-placement="bottom"]').should('be.visible');
cy.get('[data-popper-placement="bottom"]').contains(
'Current subdomain does not have the correct ability to use PagerDuty Live',
);
});

it('Application indicates when polling is disabled through url parameter disable-polling', () => {
cy.visit('http://localhost:3000/pd-live-react/?disable-polling=true');

cy.get('.modal-title', { timeout: 30000 }).contains('Disclaimer & License');
cy.get('#disclaimer-agree-checkbox').click({ force: true });
cy.get('#disclaimer-accept-button').click({ force: true });
// cy.get('.modal-title', { timeout: 30000 }).contains('Disclaimer & License');
// cy.get('#disclaimer-agree-checkbox').click({ force: true });
// cy.get('#disclaimer-accept-button').click({ force: true });

cy.get('.status-beacon-ctr').trigger('mouseover');
cy.get('.status-beacon-connection').should('be.visible');
cy.get('.status-beacon-connection').contains('Live updates disabled');
cy.get('.status-beacon-ctr').realHover();
cy.get('[data-popper-placement="bottom"]').should('be.visible');
cy.get('[data-popper-placement="bottom"]').contains('Live updates disabled');
});

it('Application correctly uses url parameters since & until to query PD API', () => {
Expand All @@ -92,25 +92,18 @@ describe('PagerDuty Live', () => {
.set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
.toISOString();
const until = moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).toISOString();
cy.intercept('GET', [
'https://api.pagerduty.com/incidents',
'?limit=100&total=true&offset=0',
`&since=${since}&until=${until}*`,
].join('')).as('getUrl');

cy.visit(
`http://localhost:3000/pd-live-react/?disable-polling=true&since=${since}&until=${until}`,
);

cy.get('.modal-title', { timeout: 30000 }).contains('Disclaimer & License');
cy.get('#disclaimer-agree-checkbox').click({ force: true });
cy.get('#disclaimer-accept-button').click({ force: true });

// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(5000);
cy.requestsCountByUrl(
[
'https://api.pagerduty.com/incidents',
'?limit=100&total=true&offset=0',
`&since=${since}&until=${until}`,
'&include[]=first_trigger_log_entries&include[]=external_references',
'&sort_by=created_at:desc&statuses[]=triggered&statuses[]=acknowledged',
'&urgencies[]=high&urgencies[]=low',
].join(''),
).should('eq', 1);
cy.get('@getUrl.all').should('have.length', 1);
});
});
6 changes: 0 additions & 6 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,3 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

// Ref: https://stackoverflow.com/a/67301763
Cypress.Commands.add('requestsCountByUrl', (url) => cy.wrap().then(() => {
const requests = cy.state('requests') || [];
return requests.filter((req) => req.xhr.url.startsWith(url)).length;
}));
1 change: 1 addition & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ import './commands';

import 'cypress-fail-fast';
import '@4tw/cypress-drag-drop';
import "cypress-real-events";
19 changes: 14 additions & 5 deletions cypress/support/util/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ export const pd = api({ token: Cypress.env('PD_USER_TOKEN') });
Cypress Helpers
*/
export const acceptDisclaimer = () => {
cy.visit('/', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
});
cy.clearLocalStorage();
cy.clearAllSessionStorage();
cy.clearCookies();
cy.visit('/');
cy.get('.modal-title', { timeout: 30000 }).contains('Disclaimer & License');
cy.get('#disclaimer-agree-checkbox').click({ force: true });
cy.get('#disclaimer-accept-button').click({ force: true });
Expand All @@ -25,6 +24,8 @@ export const waitForIncidentTable = () => {
// Ref: https://stackoverflow.com/a/60065672/6480733
cy.wait(3000); // Required for query debounce
cy.get('#incident-table-ctr', { timeout: 60000 }).should('be.visible');
// will move on to next command even if table is not scrollable
cy.get('.incident-table-fixed-list').scrollTo('top', { ensureScrollable: false });
};

export const selectIncident = (incidentIdx = 0) => {
Expand All @@ -37,6 +38,14 @@ export const selectAllIncidents = () => {
cy.get('#select-all', { timeout: 20000 }).click();
};

export const checkNoIncidentsSelected = () => {
cy.get('.selected-incidents-badge').then(($el) => {
const text = $el.text();
const incidentNumbers = text.split(' ')[0].split('/');
expect(incidentNumbers[0]).to.equal('0');
});
};

export const checkActionAlertsModalContent = (content) => {
cy.wait(2000);
cy.get('.chakra-alert__title').contains(content, { timeout: 10000 });
Expand Down
Loading

0 comments on commit 94dfabb

Please sign in to comment.