From 2e6630ba1b3dd9b2f3189cdf03f6b89fbe5f1832 Mon Sep 17 00:00:00 2001 From: Michael Peterseil Date: Wed, 22 Mar 2023 11:15:27 +0100 Subject: [PATCH 1/2] Add initial cy test --- cypress.config.js | 17 +++++ cypress/e2e/OfficialDemonstration.cy.js | 98 +++++++++++++++++++++++++ cypress/fixtures/example.json | 5 ++ cypress/support/commands.js | 25 +++++++ cypress/support/component-index.html | 12 +++ cypress/support/component.js | 27 +++++++ cypress/support/e2e.js | 20 +++++ 7 files changed, 204 insertions(+) create mode 100644 cypress.config.js create mode 100644 cypress/e2e/OfficialDemonstration.cy.js create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/component-index.html create mode 100644 cypress/support/component.js create mode 100644 cypress/support/e2e.js diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 0000000..b944981 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,17 @@ +const { defineConfig } = require("cypress"); + +module.exports = defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + baseUrl: 'http://localhost:8080', + }, + + component: { + devServer: { + framework: "react", + bundler: "webpack", + }, + }, +}); diff --git a/cypress/e2e/OfficialDemonstration.cy.js b/cypress/e2e/OfficialDemonstration.cy.js new file mode 100644 index 0000000..ded4e50 --- /dev/null +++ b/cypress/e2e/OfficialDemonstration.cy.js @@ -0,0 +1,98 @@ +describe('official demonstration', () => { + it('primary use case', () => { + // TO-DO: (This is a brittle version of the cy test) + // - Refactor all cy.get() methods to use data-testid's for all getting + // - Add more assertions where appropriate + + // Enter the application and login + cy.visit('/'); + cy.get('[data-testid="start-analysis-button"]').click(); + cy.get('#accept_genie_terms').click(); + cy.get('.form-signin .btn-primary').click(); + + // Select a dataset to work with (i.e. the 'GENIE public' dataset) + cy.contains('TISSUE').parent().find('.btn-coral.dropdown-toggle').click(); + // BUG: If you click on an item in the dropdown list too quickly, even within human limits, nothing happens <- Wrong + // Or maybe it's the 'Start by selecting a dataset...' popup that's the issue? <- This is the issue + // cy.wait(4000).then(() => cy.get('.dropdown-menu.show .dropdown-item').eq(0).click()); + cy.get('.dropdown-menu.show .dropdown-item').eq(2).click(); + + // Filter dataset by specific tumor type + cy.get('.layout_rect .rectCohort').eq(0).click().should('have.class', 'selected'); + cy.get('div.dual.filter').click(); + cy.get('div.search-bar').click(); + cy.get('[data-optid="tumortype"]').click(); + // This graph is pretty tricky to select the approriate bars without data-testid's + cy.get('[aria-label="Share within Cohort: 5%; Cohort: Tissue: TCGA tumors; tumortype: lung adenocarcinoma; Count: 586; Share: 5%"]').click(); + cy.get('[aria-label="Share within Cohort: 4.4%; Cohort: Tissue: TCGA tumors; tumortype: lung squamous cell carcinoma; Count: 511; Share: 4.4%"]').click(); + // cy.get('[]').click(); // 'non-small cell lung cancer' doesn't exist in this dataset + cy.get('.btn .fa-filter').click({force: true}); + cy.get('.confirmBtn').click(); + + // Filter dataset by another tumor type + cy.get('.layout_rect .rectCohort').eq(1).click().should('not.have.class', 'selected'); + cy.get('.layout_rect .rectCohort').eq(0).click().should('have.class', 'selected'); + // cy.get('div.dual.filter').click(); + cy.get('div.search-bar').click(); + cy.get('[data-optid="tumortype"]').click(); + // This graph is pretty tricky to select the approriate bars without data-testid's + cy.get('[aria-label="Share within Cohort: 4%; Cohort: Tissue: TCGA tumors; tumortype: colon adenocarcinoma; Count: 466; Share: 4%"]').click(); + // cy.get('[]]').click(); // missing colorectal adenocarcinoma in this dataset + cy.get('[aria-label="Share within Cohort: 1.5%; Cohort: Tissue: TCGA tumors; tumortype: rectum adenocarcinoma; Count: 174; Share: 1.5%"]').click(); + cy.get('.btn .fa-filter').click({force: true}); + cy.get('.confirmBtn').click(); + + // Inspect the difference in age distribution for the two tumortype filters + cy.get('.layout_rect .rectCohort').eq(1).click().should('have.class', 'selected'); + cy.get('.layout_rect .rectCohort').eq(2).should('have.class', 'selected'); + cy.get('div.search-bar').click(); + cy.get('[data-optid="age"]').click(); + + // Compare the statistical significance of the two filters + cy.get('.task-title.btn').click(); + cy.get('.compare').click(); + // Perhaps add the mouse hover events here? + cy.get('div.search-bar').click(); + cy.get('[data-optid="gender"]').click(); + cy.get('td.action.score').eq(2).click(); + + // Split by race + cy.get('.task-title.btn').click(); + cy.get('div.dual.filter').click(); + cy.get('.layout_rect .rectCohort').eq(1).dblclick().should('have.class', 'selected'); + cy.get('div.clear-all').click(); + cy.get('div.search-bar').click(); + cy.get('[data-optid="race"]').click(); + cy.get('[aria-label="Share within Cohort: 67.9%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: white; Count: 745; Share: 67.9%"]').click(); + cy.get('[aria-label="Share within Cohort: 7.7%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: black or african american; Count: 85; Share: 7.7%"]').click(); + cy.get('[aria-label="Share within Cohort: 1.5%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: asian; Count: 17; Share: 1.5%"]').click(); + cy.get('.btn i.fa-share-alt').click({force: true}); + cy.wait(2000); // Waits for the columns to load properly before pinning, TO-DO: Replace with non-arbitrary wait + cy.get('i.fa-thumbtack').eq(1).click(); + cy.get('i.fa-thumbtack').eq(0).click(); + cy.get('.confirmBtn').click(); + + // Split by gender + cy.get('div.search-bar').click(); + cy.get('[data-optid="gender"]').click(); + cy.get('.btn i.fa-share-alt').click({force: true}); + cy.wait(2000); // Waits for the columns to load properly before pinning, TO-DO: Replace with non-arbitrary wait + cy.get('i.fa-thumbtack').eq(1).click(); //pin the gender columns as well + cy.get('i.fa-thumbtack').eq(3).click(); + cy.get('.confirmBtn').click(); + + // Something about the Kras: AA Mutation + cy.get('div.search-bar').type('kras'); + cy.get('[data-optid="ENSG00000133703"]').click(); + // cy.get('[data-optid="ENSG00000133703:aamutation"]').click(); + + //Kras data is not loading / throwing error? + + + + + + + + }) +}) \ No newline at end of file diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000..02e4254 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 0000000..66ea16e --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) \ No newline at end of file diff --git a/cypress/support/component-index.html b/cypress/support/component-index.html new file mode 100644 index 0000000..ac6e79f --- /dev/null +++ b/cypress/support/component-index.html @@ -0,0 +1,12 @@ + + + + + + + Components App + + +
+ + \ No newline at end of file diff --git a/cypress/support/component.js b/cypress/support/component.js new file mode 100644 index 0000000..0d9eef9 --- /dev/null +++ b/cypress/support/component.js @@ -0,0 +1,27 @@ +// *********************************************************** +// This example support/component.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') + +import { mount } from 'cypress/react' + +Cypress.Commands.add('mount', mount) + +// Example use: +// cy.mount() \ No newline at end of file diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js new file mode 100644 index 0000000..0e7290a --- /dev/null +++ b/cypress/support/e2e.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') \ No newline at end of file From 0ba6357b3f5d4ff028d71723b836b2c4897471cc Mon Sep 17 00:00:00 2001 From: Michael Peterseil Date: Wed, 22 Mar 2023 12:58:38 +0100 Subject: [PATCH 2/2] Finished Prelim Test --- cypress/e2e/OfficialDemonstration.cy.js | 83 ++++++++++++++++++------- cypress/support/e2e.js | 8 ++- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/cypress/e2e/OfficialDemonstration.cy.js b/cypress/e2e/OfficialDemonstration.cy.js index ded4e50..eb31d63 100644 --- a/cypress/e2e/OfficialDemonstration.cy.js +++ b/cypress/e2e/OfficialDemonstration.cy.js @@ -1,8 +1,9 @@ describe('official demonstration', () => { it('primary use case', () => { // TO-DO: (This is a brittle version of the cy test) - // - Refactor all cy.get() methods to use data-testid's for all getting + // - Refactor most cy.get() methods to use data-testid's for getting // - Add more assertions where appropriate + // - Prune arbitrary wait's // Enter the application and login cy.visit('/'); @@ -12,33 +13,38 @@ describe('official demonstration', () => { // Select a dataset to work with (i.e. the 'GENIE public' dataset) cy.contains('TISSUE').parent().find('.btn-coral.dropdown-toggle').click(); - // BUG: If you click on an item in the dropdown list too quickly, even within human limits, nothing happens <- Wrong + // BUG: If you click on the top-most item in the dropdown list too quickly, even within human limits, nothing happens <- Wrong // Or maybe it's the 'Start by selecting a dataset...' popup that's the issue? <- This is the issue // cy.wait(4000).then(() => cy.get('.dropdown-menu.show .dropdown-item').eq(0).click()); - cy.get('.dropdown-menu.show .dropdown-item').eq(2).click(); + cy.get('.dropdown-menu.show .dropdown-item').eq(1).click(); // Filter dataset by specific tumor type - cy.get('.layout_rect .rectCohort').eq(0).click().should('have.class', 'selected'); + cy.get('.layout_rect .rectCohort').eq(0).click().should('have.class', 'selected'); // For some reason it must be manually clicked in a cy test cy.get('div.dual.filter').click(); cy.get('div.search-bar').click(); cy.get('[data-optid="tumortype"]').click(); - // This graph is pretty tricky to select the approriate bars without data-testid's - cy.get('[aria-label="Share within Cohort: 5%; Cohort: Tissue: TCGA tumors; tumortype: lung adenocarcinoma; Count: 586; Share: 5%"]').click(); - cy.get('[aria-label="Share within Cohort: 4.4%; Cohort: Tissue: TCGA tumors; tumortype: lung squamous cell carcinoma; Count: 511; Share: 4.4%"]').click(); - // cy.get('[]').click(); // 'non-small cell lung cancer' doesn't exist in this dataset + + // This graph is pretty tricky to select the approriate bars without dynamic data-testid's + cy.get('[aria-label="Share within Cohort: 11.4%; Cohort: Tissue: GENIE public; tumortype: lung adenocarcinoma; Count: 12931; Share: 11.4%"]').click(); + cy.get('[aria-label="Share within Cohort: 1.4%; Cohort: Tissue: GENIE public; tumortype: lung squamous cell carcinoma; Count: 1564; Share: 1.4%"]').click(); + cy.get('[aria-label="Share within Cohort: 0.9%; Cohort: Tissue: GENIE public; tumortype: non-small cell lung cancer; Count: 971; Share: 0.9%"]').click(); + cy.get('.btn .fa-filter').click({force: true}); cy.get('.confirmBtn').click(); // Filter dataset by another tumor type - cy.get('.layout_rect .rectCohort').eq(1).click().should('not.have.class', 'selected'); - cy.get('.layout_rect .rectCohort').eq(0).click().should('have.class', 'selected'); + cy.get('.layout_rect .rectCohort').eq(0).dblclick().should('have.class', 'selected'); + cy.get('.layout_rect .rectCohort').eq(1).should('not.have.class', 'selected'); + // cy.get('div.dual.filter').click(); cy.get('div.search-bar').click(); cy.get('[data-optid="tumortype"]').click(); - // This graph is pretty tricky to select the approriate bars without data-testid's - cy.get('[aria-label="Share within Cohort: 4%; Cohort: Tissue: TCGA tumors; tumortype: colon adenocarcinoma; Count: 466; Share: 4%"]').click(); - // cy.get('[]]').click(); // missing colorectal adenocarcinoma in this dataset - cy.get('[aria-label="Share within Cohort: 1.5%; Cohort: Tissue: TCGA tumors; tumortype: rectum adenocarcinoma; Count: 174; Share: 1.5%"]').click(); + + // This graph is pretty tricky to select the approriate bars without dynamic data-testid's + cy.get('[aria-label="Share within Cohort: 5.7%; Cohort: Tissue: GENIE public; tumortype: colon adenocarcinoma; Count: 6386; Share: 5.7%"]').click(); + cy.get('[aria-label="Share within Cohort: 2.1%; Cohort: Tissue: GENIE public; tumortype: colorectal adenocarcinoma; Count: 2377; Share: 2.1%"]').click(); + cy.get('[aria-label="Share within Cohort: 1.6%; Cohort: Tissue: GENIE public; tumortype: rectum adenocarcinoma; Count: 1841; Share: 1.6%"]').click(); + cy.get('.btn .fa-filter').click({force: true}); cy.get('.confirmBtn').click(); @@ -54,22 +60,26 @@ describe('official demonstration', () => { // Perhaps add the mouse hover events here? cy.get('div.search-bar').click(); cy.get('[data-optid="gender"]').click(); + cy.wait(3000); cy.get('td.action.score').eq(2).click(); // Split by race cy.get('.task-title.btn').click(); cy.get('div.dual.filter').click(); cy.get('.layout_rect .rectCohort').eq(1).dblclick().should('have.class', 'selected'); + cy.get('div.clear-all').click(); cy.get('div.search-bar').click(); cy.get('[data-optid="race"]').click(); - cy.get('[aria-label="Share within Cohort: 67.9%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: white; Count: 745; Share: 67.9%"]').click(); - cy.get('[aria-label="Share within Cohort: 7.7%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: black or african american; Count: 85; Share: 7.7%"]').click(); - cy.get('[aria-label="Share within Cohort: 1.5%; Cohort: #1 Tumortype: Lung squamous cell carcinoma/Lung adenocarcinoma; race: asian; Count: 17; Share: 1.5%"]').click(); + + cy.get('[aria-label="Share within Cohort: 73%; Cohort: #1 Tumortype: Lung adenocarcinoma/Non-small cell lung cancer/Lung squamous cell carcinoma; race: white; Count: 11288; Share: 73%"]').click(); + cy.get('[aria-label="Share within Cohort: 7.3%; Cohort: #1 Tumortype: Lung adenocarcinoma/Non-small cell lung cancer/Lung squamous cell carcinoma; race: asian; Count: 1123; Share: 7.3%"]').click(); + cy.get('[aria-label="Share within Cohort: 6.9%; Cohort: #1 Tumortype: Lung adenocarcinoma/Non-small cell lung cancer/Lung squamous cell carcinoma; race: black; Count: 1074; Share: 6.9%"]').click(); + cy.get('.btn i.fa-share-alt').click({force: true}); cy.wait(2000); // Waits for the columns to load properly before pinning, TO-DO: Replace with non-arbitrary wait - cy.get('i.fa-thumbtack').eq(1).click(); - cy.get('i.fa-thumbtack').eq(0).click(); + cy.get('i.fa-thumbtack').eq(1).click({force: true}); + cy.get('i.fa-thumbtack').eq(0).click({force: true}); cy.get('.confirmBtn').click(); // Split by gender @@ -77,16 +87,41 @@ describe('official demonstration', () => { cy.get('[data-optid="gender"]').click(); cy.get('.btn i.fa-share-alt').click({force: true}); cy.wait(2000); // Waits for the columns to load properly before pinning, TO-DO: Replace with non-arbitrary wait - cy.get('i.fa-thumbtack').eq(1).click(); //pin the gender columns as well - cy.get('i.fa-thumbtack').eq(3).click(); + cy.get('i.fa-thumbtack').eq(1).click({force: true}); //pin the gender columns as well + cy.get('i.fa-thumbtack').eq(3).click({force: true}); cy.get('.confirmBtn').click(); - // Something about the Kras: AA Mutation + // Filter each race-gender pair by KRAS: AA Mutation (P.Gly12Cys) cy.get('div.search-bar').type('kras'); cy.get('[data-optid="ENSG00000133703"]').click(); - // cy.get('[data-optid="ENSG00000133703:aamutation"]').click(); + cy.wait(1500); + cy.get('[data-optid="ENSG00000133703:aamutation"]').click(); + + // This graph is pretty tricky to select the approriate bars without data-testid's + cy.get('[aria-label="Share within Cohort: 1.3%; Cohort: #6 Gender: Female; ENSG00000133703-aamutation: p.Gly12Cys; Count: 8; Share per Cohort: 1.3%"]').click(); + cy.get('[aria-label="Share within Cohort: 5.4%; Cohort: #7 Gender: Male; ENSG00000133703-aamutation: p.Gly12Cys; Count: 27; Share per Cohort: 5.4%"]').click(); + cy.get('[aria-label="Share within Cohort: 12.3%; Cohort: #8 Gender: Female; ENSG00000133703-aamutation: p.Gly12Cys; Count: 77; Share per Cohort: 12.3%"]').click(); + cy.get('[aria-label="Share within Cohort: 8.5%; Cohort: #9 Gender: Male; ENSG00000133703-aamutation: p.Gly12Cys; Count: 38; Share per Cohort: 8.5%"]').click(); + cy.get('[aria-label="Share within Cohort: 14.4%; Cohort: #10 Gender: Female; ENSG00000133703-aamutation: p.Gly12Cys; Count: 942; Share per Cohort: 14.4%"]').click(); + cy.get('[aria-label="Share within Cohort: 10.6%; Cohort: #11 Gender: Male; ENSG00000133703-aamutation: p.Gly12Cys; Count: 505; Share per Cohort: 10.6%"]').click(); + + cy.get('.btn .fa-filter').click({force: true}); + cy.get('.confirmBtn').click(); + + // Inspect the prevalence of this Mutation + cy.get('.task-title.btn').click(); + cy.get('div.prevalence').click(); + + cy.wait(3000); + cy.get('div.prevalence-cohort-pack').eq(0).find('.prev-checkbox').eq(3).click(); + cy.get('div.prevalence-cohort-pack').eq(0).find('.prev-checkbox').eq(2).click(); + cy.get('div.prevalence-cohort-pack').eq(0).find('.prev-checkbox').eq(1).click(); + cy.get('div.prevalence-cohort-pack').eq(0).find('.prev-checkbox').eq(0).click(); + + cy.get('div.prevalence-cohort-pack').eq(1).find('.prev-checkbox').eq(2).click(); + + - //Kras data is not loading / throwing error? diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index 0e7290a..809f4de 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -14,7 +14,13 @@ // *********************************************************** // Import commands.js using ES2015 syntax: -import './commands' +import './commands'; + +Cypress.on('uncaught:exception', (err, runnable) => { + // returning false here prevents Cypress from + // failing the test + return false + }); // Alternatively you can use CommonJS syntax: // require('./commands') \ No newline at end of file