diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..776ffb578 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 000000000..3e4c35d37 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,57 @@ +name: CI + +on: + push: + branches-ignore: + - '**' + #branches: [ develop ] + +jobs: + build: + name: Install deps and Build + runs-on: ubuntu-18.04 + steps: + ## Install deps and build IVA + - uses: actions/checkout@v2 + - name: IVA Npm install and Prepare + run: | + npm install bower + npm install && npm run prepare + - name: Jsorolla Npm install + run: | + git submodule update --init + cd lib/jsorolla + npm install bower + npm install + - name: Npm build + run: npm run build + - name: LS + run: ls + - name: Upload webpack artifact + uses: actions/upload-artifact@v2 + with: + name: webpack-artifact + path: build + retention-days: 1 + + deploy: + name: Publish Docker image in DockerHub repository + runs-on: ubuntu-18.04 + needs: build + steps: + ## Publish docker image to DockerHub + - uses: actions/checkout@v2 + - name: Download webpack artifact + uses: actions/download-artifact@v2 + with: + name: webpack-artifact + path: build + - name: Read package.json + uses: "tyankatsu0105/read-package-version-actions@v1" + id: package-version + - name: Show version number + run: echo "Version is ${{ steps.package-version.outputs.version }}" + - name: Login to dockerhub + run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login --username ${{ secrets.DOCKER_HUB_USER }} --password-stdin + - name: Build and Publish Docker image + run: python3 ./docker/docker-build.py push --images app --tag ${{ steps.package-version.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..5b95be219 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: "release" + +on: + push: + branches-ignore: + - '**' + #branches: [ master ] + +jobs: + build: + name: App build + runs-on: ubuntu-18.04 + steps: + ## Install deps and build IVA + - uses: actions/checkout@v2 + - name: IVA Npm install and Prepare + run: | + npm install bower + npm install && npm run prepare + - name: Jsorolla Npm install + run: | + git submodule update --init + cd lib/jsorolla + npm install bower + npm install + - name: Npm build + run: npm run build + - name: Read package.json + uses: "tyankatsu0105/read-package-version-actions@v1" + id: package-version + - name: Show version number + run: | + echo "Version is ${{ steps.package-version.outputs.version }}" + - name: Create release + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + draft: true + automatic_release_tag: "v${{ steps.package-version.outputs.version }}" + title: "v${{ steps.package-version.outputs.version }}" + prerelease: false + files: | + iva-${{ steps.package-version.outputs.version }}.tar.gz diff --git a/.gitignore b/.gitignore index 689a566d8..89514c4e7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules web_modules private web_modules +iva-*.tar.gz # General *.jar diff --git a/build-vendors.js b/build-vendors.js deleted file mode 100755 index 8edc75f5c..000000000 --- a/build-vendors.js +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env node - -const fs = require("fs"); -let shelljs = require('shelljs'); -let DOMParser = require("xmldom").DOMParser; - -const VENDOR_FOLDER = "build/vendors/"; - -// Copy Polymer dependency -shelljs.cp("-rL", "node_modules/@polymer", VENDOR_FOLDER); - -// Copy vendor dependencies -fs.readFile("build/index.html", "utf8", function (err2, content) { - let parser = new DOMParser(); - let htmlDoc = parser.parseFromString(content, "text/html"); - - let links = htmlDoc.getElementsByTagName("link"); - for (let i = 0; i < links.length; i++) { - let href = links[i].getAttribute("href"); - let arr = href.split("node_modules/"); - if (arr.length === 2) { - let path = arr[1].substring(0, arr[1].lastIndexOf("/")); - shelljs.mkdir("-p", VENDOR_FOLDER + path); - shelljs.cp("-R", "node_modules/" + arr[1], VENDOR_FOLDER + path); - } - } - - let scripts = htmlDoc.getElementsByTagName("script"); - for (let i = 0; i < scripts.length; i++) { - let src = scripts[i].getAttribute("src"); - let arr = src.split("node_modules/"); - if (arr.length === 2) { - let path = arr[1].substring(0, arr[1].lastIndexOf("/")); - shelljs.mkdir("-p", VENDOR_FOLDER + path); - shelljs.cp("node_modules/" + arr[1], VENDOR_FOLDER + path); - } - } - - content = replaceContentIndex(content); - fs.writeFile('build/index.html', content, (err) => { - if (err) throw err; - console.log('The file has been saved!'); - }); - -}); - -fs.readFile("build/iva-app.html", "utf8", function (err2, content) { - content = replaceContentIva(content); - fs.writeFile('build/iva-app.html', content, (err) => { - if (err) throw err; - console.log('The file has been saved!'); - }); - -}); - - -function replaceContentIva(content){ - let nodeModulesRegex = /\.\.\/node_modules/g; - let nodeModulesReplacement = "vendors"; - let libJsorollaRegex = /\.\.\/lib\/jsorolla\/src/g; - let libJsorollaReplacement = "jsorolla/dist/js"; - - content = replaceContent(nodeModulesRegex, nodeModulesReplacement, content); - content = replaceContent(libJsorollaRegex, libJsorollaReplacement, content); - - return content -} - -function replaceContentIndex(content){ - let nodeModulesRegex = /\.\.\/\.\.\/node_modules/g; - let nodeModulesReplacement = "vendors"; - let libJsorollaRegex = /\.\.\/\.\.\/lib\/jsorolla/g; - let libJsorollaReplacement = "jsorolla"; - let confRegex = /\.\.\/conf/g; - let confReplacement = "conf"; - let ivaRegex = /\.\.\/iva-app/g; - let ivaReplacement = "iva-app"; - let utilsRegex = /\.\.\/utils/g; - let utilsReplacement = "utils"; - - - content = replaceContent(nodeModulesRegex, nodeModulesReplacement, content); - content = replaceContent(libJsorollaRegex, libJsorollaReplacement, content); - content = replaceContent(confRegex, confReplacement, content); - content = replaceContent(ivaRegex, ivaReplacement, content); - content = replaceContent(utilsRegex, utilsReplacement, content); - - return content -} - -function replaceContent(regex, replacement, content){ - - //let htmlDoc = parser.parseFromString(content, "text/html"); - return content.replace(regex, replacement); -} - - - diff --git a/credentials.sh b/credentials.sh deleted file mode 100755 index 09266cf89..000000000 --- a/credentials.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo -n "Enter your Opencga Username [ENTER]: " -read username -stty -echo -printf "Enter your Opencga password [ENTER]: " -read password -stty echo - -CYPRESS_username=$username CYPRESS_password=$password "$@" diff --git a/cypress.json b/cypress.json index 36c445610..f30e18d5d 100644 --- a/cypress.json +++ b/cypress.json @@ -2,5 +2,12 @@ "baseUrl": "http://localhost:3000/src/", "chromeWebSecurity": false, "viewportWidth": 1600, - "viewportHeight": 660 + "viewportHeight": 660, + "reporter": "mochawesome", + "reporterOptions": { + "overwrite": false, + "html": false, + "json": true + } + } diff --git a/cypress/credentials.bat b/cypress/credentials.bat new file mode 100644 index 000000000..c7f742a26 --- /dev/null +++ b/cypress/credentials.bat @@ -0,0 +1,61 @@ +@echo off + setlocal enableextensions disabledelayedexpansion + +rem set the username using a plain prompt + SET /p CYPRESS_username=Enter your Opencga Username [ENTER]: +rem Call the subroutine to get the password + call :getPassword CYPRESS_password +rem set the study using a plain prompt + SET /p CYPRESS_study=Enter the FQN of the Study you want to test (leave empty for default) [ENTER]: + +rem Echo what the function returns + if defined CYPRESS_password ( + SET CYPRESS_password=%CYPRESS_password% + rem it launches whatever is passed to the script as param + %* + ) else ( + echo Password must be defined + ) + +rem End of the process + endlocal + exit /b + + +rem Subroutine to get the password +:getPassword returnVar + setlocal enableextensions disabledelayedexpansion + set "_password=" + + rem We need a backspace to handle character removal + for /f %%a in ('"prompt;$H&for %%b in (0) do rem"') do set "BS=%%a" + + rem Prompt the user + set /p "=Enter your Opencga Password [ENTER]: " nul') do if not defined key set "key=%%a" + set "key=%key:~-1%" + + rem handle the keypress + rem if No keypress (enter), then exit + rem if backspace, remove character from password and console + rem else add character to password and go ask for next one + if defined key ( + if "%key%"=="%BS%" ( + if defined _password ( + set "_password=%_password:~0,-1%" + setlocal enabledelayedexpansion & set /p "=!BS! !BS!" CYPRESS_study +#"re-opencgahadoop@100k_genomes_grch37_germline:RD37" +#"re-opencgahadoop@100k_genomes_grch38_germline:RD38" +#"re-opencgahadoop@100k_genomes_grch38_germline:CG38" +#"re-opencgahadoop@100k_genomes_grch38_somatic:CS38" +#study=re-opencgahadoop@100k_genomes_grch38_somatic:CS38 + +CYPRESS_username=$username CYPRESS_password=$password CYPRESS_study=$study "$@" diff --git a/cypress/e2e-runner.bat b/cypress/e2e-runner.bat new file mode 100644 index 000000000..90af1553d --- /dev/null +++ b/cypress/e2e-runner.bat @@ -0,0 +1,117 @@ +@echo off +setlocal EnableExtensions EnableDelayedExpansion + +rem This script launches IVA e2e tests over one or more Opencga studies in Windows env +rem Params: +rem -u Opencga username. +rem -s Comma-separated list of studies. Please wrap the list in quotes in case of more that one study +rem -h Prints command description +rem +rem If -u (username) and -s (studies) params are not provided, it prompts for Opencga username, password, and a comma-separated list of studies + + +:parse +IF "%~1"=="" GOTO endparse +IF "%~1"=="-u" SET opencgaUser=%~2 +IF "%~1"=="-s" SET studies=%~2 +IF "%~1"=="-h" call :help & goto :eof +SHIFT +GOTO parse +:endparse + +if not defined opencgaUser ( +rem set the username using a plain prompt + SET /p opencgaUser=Enter your Opencga Username [ENTER]: + if not defined opencgaUser ( + echo Username must be defined + goto :eof + ) +) + +rem Call the subroutine to get the password +call :getPassword opencgaPassword +if not defined opencgaPassword ( + echo Password must be defined + goto :eof +) + +if not defined studies ( +rem set the username using a plain prompt + SET /p studies="Enter the the FQN (comma-separated) of the studies you want to test [ENTER]:" + if not defined studies ( + echo studies must be defined + goto :eof + ) +) + + +rem echo %opencgaUser% - %opencgaPassword% - %studies% + +rem Iterate over studies and +for %%a in ("%studies:,=" "%") do ( +set tmp=%%~na +set study=!tmp::=! +echo STUDY: %%~a DIR: !study! +rem mkdir !study! && dir !study! +(if exist mochawesome-report rmdir /S/Q mochawesome-report)^ + && call npx cypress run --env username=%opencgaUser%,password=%opencgaPassword%,study=%%~a --config videosFolder="cypress/videos/!study!",screenshotsFolder="cypress/screenshots/!study!" --headless --spec "cypress/integration/*.js"^ + & call npx mochawesome-merge mochawesome-report/*.json -o mochawesome-report/cypress-combined-report.json^ + && call npx marge --reportFilename !study!.html --charts --timestamp _HH-MM_dd-mm-yyyy --reportPageTitle IVA_%%~a --reportTitle IVA__%%~a --reportDir report mochawesome-report/cypress-combined-report.json^ + && (if exist mochawesome-report rmdir /S/Q mochawesome-report) +) + +rem End of the process +endlocal +exit /b + + +:help +setlocal EnableDelayedExpansion +set u="Usage: %~n0%~x0 [-u ] [-s ]" +echo(!~u! +echo Launches IVA e2e tests over one or more Opencga studies. +echo Options: +echo -u Opencga username. +echo -s Comma-separated list of studies. Please wrap the list in quotes in case of more that one study +echo -h Prints command description +endlocal & exit /b 0 + + +rem Subroutine to get the password +:getPassword returnVar + setlocal enableextensions disabledelayedexpansion + set "_password=" + + rem We need a backspace to handle character removal + for /f %%a in ('"prompt;$H&for %%b in (0) do rem"') do set "BS=%%a" + + rem Prompt the user + set /p "=Enter your Opencga Password [ENTER]: " nul') do if not defined key set "key=%%a" + set "key=%key:~-1%" + + rem handle the keypress + rem if No keypress (enter), then exit + rem if backspace, remove character from password and console + rem else add character to password and go ask for next one + if defined key ( + if "%key%"=="%BS%" ( + if defined _password ( + set "_password=%_password:~0,-1%" + setlocal enabledelayedexpansion & set /p "=!BS! !BS!"] [-s ] + Launches IVA e2e tests over one or more Opencga studies. + Options: + -u Opencga username. + -s Comma-separated list of studies. + -h Prints command description +TEXT +} + + +while getopts :u:s:h opts; do + case ${opts} in + u) username=${OPTARG} ;; + s) studies=${OPTARG} ;; + h) Help "$@" + exit 0;; + *) ;; + esac +done + +if test ! $username; then + # if username not defined as opt + echo -n "Enter your Opencga Username [ENTER]: " + read username +fi + +# set password +stty -echo +printf "Enter your Opencga Password [ENTER]: " +read password +stty echo + +if test ! "$studies"; then + # if studies not defined as opt (comma separated) + echo -en "\nEnter the FQN (comma separated) of the studies you want to test (leave empty for default) [ENTER]: " + read str_studies + readarray -d , -t studies<<<"$str_studies" +fi + +# iterate over studies and run the test defined in --spec +export CYPRESS_username=$username +export CYPRESS_password=$password +for study in "${studies[@]}" +do + echo "$study" + rm -rf mochawesome-report/ && \ + CYPRESS_study="$study" npx cypress run --config videosFolder="cypress/videos/$study",screenshotsFolder="cypress/screenshots/$study" --headless --spec 'cypress/integration/002-login.js'; \ + npx mochawesome-merge mochawesome-report/*.json -o mochawesome-report/cypress-combined-report.json && \ + npx marge --reportFilename "$study".html --charts --timestamp _HH-MM_dd-mm-yyyy --reportPageTitle "IVA $study" --reportTitle "IVA study: $study" --reportDir ./report mochawesome-report/cypress-combined-report.json && \ + rm -rf mochawesome-report/ +done +spd-say 'end to end test completed' diff --git a/cypress/integration/001-header-bar-pre-login.spec.js b/cypress/integration/001-header-bar-pre-login.spec.js new file mode 100644 index 000000000..0379ebcc9 --- /dev/null +++ b/cypress/integration/001-header-bar-pre-login.spec.js @@ -0,0 +1,41 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {TIMEOUT} from "../plugins/constants.js"; + + +/** + * Header bar (pre-login) + */ +context("1 - Header bar (pre-login): checks on Header Bar elements", () => { + before(() => { + cy.visit("http://localhost:3000/src/"); + + }); + + it("1.1 - check login page content", () => { + cy.get("#loginButton", {timeout: TIMEOUT}).should("be.visible"); + cy.get("#loginButton").click(); + cy.get("#opencgaUser").should("be.visible"); + cy.get("#opencgaPassword").should("be.visible"); + }); + + it("1.2 - check header-bar icons resolve correctly", () => { + cy.get("a.navbar-brand").first().click(); + cy.get("#welcome-page-title", {timeout: TIMEOUT}).contains("Interactive Variant Analysis"); + + }); +}); diff --git a/cypress/integration/002-login.js b/cypress/integration/002-login.js new file mode 100644 index 000000000..a55700031 --- /dev/null +++ b/cypress/integration/002-login.js @@ -0,0 +1,56 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {TIMEOUT} from "../plugins/constants.js"; + + +context("2 - Login", () => { + beforeEach(() => { + cy.visit("http://localhost:3000/src/#login"); + }); + + it("2.1 - login unsuccessful", () => { + cy.get("#opencgaUser").type("demo2"); + cy.get("#opencgaPassword").type("demo2"); + cy.get("form#formLogin").submit(); + cy.get("#error").should("be.visible"); + cy.get("#error").contains("Incorrect user or password."); + }); + + it("2.2 - login successful", () => { + + const username = Cypress.env("username"); + const password = Cypress.env("password"); + + expect(username, "username was set").to.be.a("string").and.not.be.empty; + expect(password, "password was set").to.be.a("string").and.not.be.empty; + cy.get("#opencgaUser").type(username); + cy.get("#opencgaPassword").type(password); + cy.get("form#formLogin").submit(); + + cy.get(".login-overlay", {timeout: TIMEOUT}).should("be.visible"); + cy.get(".login-overlay", {timeout: TIMEOUT}).should("not.exist"); + + cy.url().should("include", "#home", {timeout: TIMEOUT}); + + // switch to defined Study + if (Cypress.env("study")) { + cy.get(`a[data-fqn="${Cypress.env("study")}"]`, {timeout: 60000}).click({force: true}); + } + cy.get(".subtitle", {timeout: TIMEOUT}).contains("Interactive Variant Analysis"); + }); + +}); diff --git a/cypress/integration/003-header-bar-post-login.spec.js b/cypress/integration/003-header-bar-post-login.spec.js new file mode 100644 index 000000000..6276c4528 --- /dev/null +++ b/cypress/integration/003-header-bar-post-login.spec.js @@ -0,0 +1,81 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, checkResults, checkResultsOrNot} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +/** + * Header bar (post-login) + */ +context("3 - Header bar (post-login): Checks each menu item in header-bar resolves correctly", () => { + before(() => { + login(); + }); + + it("3.1 - checks Variant Browser menu item", () => { + cy.get("a[data-id=browser]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Variant Browser"); // should assertion comes from Chai and it follows its logic + checkResults("variant-browser-grid"); + + }); + + it("3.2 - checks Case Portal menu item", () => { + cy.get("a[data-id=clinicalAnalysisPortal]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Case Portal"); + checkResults("opencga-clinical-analysis-grid"); + }); + + it("3.3 - checks Sample Browser menu item", () => { + cy.get("a[data-id=sample]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Sample Browser"); + checkResults("opencga-sample-grid"); + }); + + it("3.4 - checks Individual Browser menu item", () => { + cy.get("a[data-id=individual]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Individual Browser"); // should assertion comes from Chai and it follows its logic + checkResults("opencga-individual-grid"); + + }); + + it("3.5 - checks Family Browser menu item", () => { + cy.get("a[data-id=family]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Family Browser"); // should assertion comes from Chai and it follows its logic + checkResultsOrNot("opencga-family-grid"); + }); + + it("3.6 - checks study selector menu items", () => { + // switching between all the studies + cy.get("a[data-study]").each(($el, index, $list) => { + const study = $el.data("study"); + const studyName = $el.data("study-name"); + const projectName = $el.data("project-name"); + cy.get(`a[data-study='${study}'][data-project-name="${projectName}"]`).click({force: true}); + cy.get("a[data-cy='active-study']").should("be.visible").and("contain", studyName).and("contain", projectName); + }); + }); + + it("3.7 - checks User menu items", () => { + cy.get("li[data-cy='user-menu'] > a").click(); + cy.get("a[data-user-menu='account']").click(); + cy.get("div.page-title h2").should("be.visible").and("contain", "Your profile"); + + // cy.get("li[data-cy='user-menu'] > a").click(); + // cy.get("a[data-user-menu='logout']").click(); // TODO fix it makes Family Browser test fails because somehow it is still pending. + + }); +}); diff --git a/cypress/integration/004-opencga-variant-browser.spec.js b/cypress/integration/004-opencga-variant-browser.spec.js new file mode 100644 index 000000000..cfef8921d --- /dev/null +++ b/cypress/integration/004-opencga-variant-browser.spec.js @@ -0,0 +1,346 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, randomString, checkResults, checkResultsOrNot, Facet, changePage} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + +context("4. Variant Browser", () => { + before(() => { + login(); + }); + + beforeEach(() => { + cy.get("a[data-id=browser]", {timeout: TIMEOUT}).click({force: true}); + }); + + it("4.1 Columns Visibility", () => { + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Variant Browser"); + + checkResults("variant-browser-grid"); + + cy.get("variant-browser-grid .columns-toggle-wrapper button").should("be.visible").and("contain", "Columns").click(); + cy.get("variant-browser-grid .columns-toggle-wrapper ul li").and("have.length.gt", 1); + + cy.get("variant-browser-grid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // deactivate all the columns + cy.get("variant-browser-grid .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.lengthOf", 1); + + cy.get("variant-browser-grid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // reactivate all the columns + cy.get("variant-browser-grid .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.length.gt", 1); + + }); + + // Variant Browser: Filter controls + it("4.2 Create/Delete canned filter", () => { + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Variant Browser"); + + cy.get("input[value*=LoF]").click({force: true}); + cy.get("opencga-active-filters").contains("Consequence Types 9"); + + cy.get("button[data-cy='filter-button']").click({force: true}); + // cy.get("ul.saved-filter-wrapper a").contains("Save filter...").click(); // it also works + cy.get("ul.saved-filter-wrapper a[data-action='active-filter-save']").contains("Save filter...").click(); + + const name = randomString(5); + // cy.get("input[data-cy='modal-filter-name']").type(name); // TODO Cypress doesn't type the entire string. https://github.com/cypress-io/cypress/issues/5480 invoke("val") is a workaround + cy.get("input[data-cy='modal-filter-name']").invoke("val", name); + cy.get("input[data-cy='modal-filter-description']").type(randomString(3)); + cy.get("button[data-cy='modal-filter-save-button']").click(); // confirm save + + cy.get(".swal2-actions").contains(/Yes|OK/).click(); // dismiss notification (either new filter or overwrite a saved one) + cy.get("button[data-cy='filter-button']").click(); + cy.get("ul.saved-filter-wrapper").contains(name); + cy.get(`span.action-buttons i[data-cy=delete][data-filter-id='${name}']`).click(); + cy.get(".swal2-title").contains("Are you sure?"); + cy.get(".swal2-confirm").click(); // confirm deletion action + + // cy.get(".swal2-content", {timeout: TIMEOUT}).contains("Filter has been deleted."); // this selector doesn't work without .should("be.visible") assertion because it refers to the previous #swal2-content which has been detatched from DOM before + cy.contains(".swal2-content", "Filter has been deleted", {timeout: TIMEOUT}).should("be.visible"); + cy.get(".swal2-confirm").click({force: true}); // dismiss confirmation modal + cy.get("opencga-active-filters button[data-filter-name='ct']").click(); + }); + + // Variant Browser: Individual filters + it("4.3 Pagination", () => { + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Variant Browser"); // should assertion comes from Chai and it follows its logic + checkResults("variant-browser-grid"); + changePage("variant-browser-grid", 2); + checkResults("variant-browser-grid"); + changePage("variant-browser-grid", 1); + checkResults("variant-browser-grid"); + }); + + it("4.4 Filters. Study and Cohorts: Cohort Alternate Stats", () => { + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Variant Browser"); // should assertion comes from Chai and it follows its logic + cy.get("variant-browser a[href='#filters_tab']").click(); + // Study and Cohorts: Cohort Alternate Stats + // TODO add condition + /* cy.get("cohort-stats-filter i[data-cy='study-cohort-toggle']").first({timeout: TIMEOUT}).should("be.visible").click(); + cy.get("cohort-stats-filter input[data-field='value']").first({timeout: TIMEOUT}).type("0.00001"); // set ALL cohort + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='cohortStatsAlt']").contains("Cohort ALT Stats"); + cy.get("opencga-active-filters button[data-filter-name='cohortStatsAlt']").click();*/ + + }); + + it("4.5 Filters. Genomic: Genomic Location", () => { + cy.get("opencga-variant-filter a[data-accordion-id='Genomic']").click(); + cy.get("region-filter textarea").type("1:5000000-10000000"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='region']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.6 Filters. Genomic: Feature IDs", () => { + cy.get("feature-filter input").type("C5{enter}rs4680{enter}"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='xref']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.7 Filters. Genomic: Disease Panels", () => { + // Genomic: Disease Panels + // TODO decomment once opencga error 'URI Too Long' is fixed + // disease-panel-filter select + button + // cy.get("disease-panel-filter").find(" a").contains("Childhood onset dystonia or chorea or related movement disorder").click({force:true}) // URI too long + // cy.get("disease-panel-filter").find(" a").contains("Amelogenesis imperfecta").click({force:true}) + // cy.get("div.search-button-wrapper button").click(); + // + // checkResultsOrNot("variant-browser-grid") + + // NOTE Covid19... is the first URI too long + /* cy.get("disease-panel-filter div.dropdown-menu a").each(el => { + + // cannot use cy.wrap(el) here. disease-panel-filter div.dropdown-menu is refreshed on click on buttons and DOM refs are broken (https://github.com/cypress-io/cypress/issues/7306) + const id = el.attr("id"); + cy.get("#" + id).should("exist").click({force: true}); + //cy.wrap(el).should("exist").click({force: true}); + cy.get("div.search-button-wrapper button").click(); + checkResultsOrNot("variant-browser-grid"); + cy.wait(2000); + cy.get("opencga-active-filters button[data-filter-name='panel']").click(); + + + });*/ + }); + + it("4.8 Filters. Genomic: Gene Biotype", () => { + // Genomic: Gene Biotype + cy.get("biotype-filter button").click(); + cy.get("biotype-filter input[type='search']").type("protein"); // typing protein_coding using autocomplete + cy.get("biotype-filter div.dropdown-menu").find("a").should("have.length", 1); + cy.get("biotype-filter div.dropdown-menu a").click(); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='biotype']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.9 Filters. Genomic: Variant", () => { + // Genomic: Variant type cy.get('.magic-checkbox-wrapper > :nth-child(1) > label') + cy.get("variant-type-filter input[value='SNV'] + label").click({force: true}); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='type']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.10 Filters. Consequence type: LoF", () => { + // Consequence type: SO Term - LoF Enabled + cy.get("opencga-variant-filter a[data-accordion-id='ConsequenceType']").click(); + cy.get("consequence-type-select-filter input[value='Loss-of-Function (LoF)'").click({force: true}); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + }); + + it("4.11 Filters. Consequence type: Missense", () => { + // Consequence type: SO Term - Use example: Missense + cy.get("consequence-type-select-filter button").click(); + cy.get("consequence-type-select-filter input[type='search']").type("miss"); // typing missense using autocomplete + cy.get("consequence-type-select-filter div.dropdown-menu").find("a").should("have.length", 1); + cy.get("consequence-type-select-filter div.dropdown-menu a").click(); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='ct']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.12 Filters. Population Frequency: 1000 Genomes - AFR < 0.0001 AND EUR > 0.0001", () => { + // Population Frequency: 1000 Genomes - AFR < 0.0001 AND EUR > 0.0001 + cy.get("opencga-variant-filter a[data-accordion-id='PopulationFrequency']").click(); + cy.get("population-frequency-filter i[data-cy='pop-freq-toggle-1kG_phase3']").click(); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-1kG_phase3']").should("be.visible"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-1kG_phase3'] div[data-cy='number-field-filter-wrapper-AFR'] input[data-field='value']").type("0.0001"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-1kG_phase3'] div[data-cy='number-field-filter-wrapper-AFR'] select[data-field='comparator']").select("<"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-1kG_phase3'] div[data-cy='number-field-filter-wrapper-EUR'] input[data-field='value']").type("0.0001"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-1kG_phase3'] div[data-cy='number-field-filter-wrapper-EUR'] select[data-field='comparator']").select(">"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='populationFrequencyAlt']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.13 Filters. Population Frequency: gnomAD - Set all < 0.00001", () => { + // Population Frequency: gnomAD - Set all < 0.00001 + cy.get("population-frequency-filter i[data-cy='pop-freq-toggle-GNOMAD_GENOMES']").click(); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-GNOMAD_GENOMES']").should("be.visible"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-GNOMAD_GENOMES'] div[data-cy='number-field-filter-wrapper-AFR'] input[data-field='value']").type("0.0001"); + cy.get("population-frequency-filter div[data-cy='pop-freq-codes-wrapper-GNOMAD_GENOMES'] div[data-cy='number-field-filter-wrapper-AFR'] select[data-field='comparator']").select("<"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='populationFrequencyAlt']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.14 Filters. Clinical and Disease: ClinVar Accessions: Pathogenic", () => { + // Clinical and Disease: ClinVar Accessions Use example: Pathogenic + cy.get("opencga-variant-filter a[data-accordion-id='Clinical']").click(); + cy.get("clinvar-accessions-filter select").select("Pathogenic", {force: true}); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='clinicalSignificance']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.15 Filters. Clinical and Disease: Full text: Mortality", () => { + // Clinical and Disease: Full text Use example: Mortality + cy.get("fulltext-search-accessions-filter textarea").type("Mortality"); + // cy.get("fulltext-search-accessions-filter textarea").type("centroid"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='traits']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.16 Filters. GO", () => { + // TODO cannot relies on data-nodeid because the order in not guaranteed + // cy.get("go-accessions-filter > button").click(); + // cy.get(".modal-body .list-group-item[data-nodeid='2'] > .expand-icon").click(); // click on cellular component + // cy.get(".modal-body .list-group-item[data-nodeid='2'] > .expand-icon").click(); // click on protein-containing complex + // cy.get(".modal-body .list-group-item[data-nodeid='3'] > .expand-icon").click(); // click on bcl3 + + // TODO you cannot tell in advance which is present in the study + // Phenotype: HPO Accessions Use example + /* cy.get("hpo-accessions-filter > textarea").type("HP:0041054"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='annot-hpo']").click();*/ + }); + + it("4.17 Filters. Deleteriousness: Sift / Polyphen - OR operation", () => { + // Deleteriousness: Sift / Polyphen - OR operation + cy.get("opencga-variant-filter a[data-accordion-id='Deleteriousness']").click(); + cy.get("protein-substitution-score-filter .sift input[type='text']").type("0.1"); + cy.get("protein-substitution-score-filter .polyphen input[type='text']").type("0.1"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='protein_substitution']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.18 Filters. Deleteriousness: Sift / Polyphen - AND operation", () => { + // Deleteriousness: Sift / Polyphen - AND operation + cy.get("protein-substitution-score-filter .sift input[type='text']").type("0.1"); + cy.get("protein-substitution-score-filter .polyphen input[type='text']").type("0.1"); + cy.get("protein-substitution-score-filter .rating-label-and").click(); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='protein_substitution']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.19 Filters. Conservation: PhyloP", () => { + // Conservation: PhyloP Use example + cy.get("opencga-variant-filter a[data-accordion-id='Conservation']").click(); + cy.get("conservation-filter .cf-phylop input[type='text']").type("1"); + cy.get("conservation-filter .cf-phastCons input[type='text']").type("1"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-browser-grid"); + cy.get("opencga-active-filters button[data-filter-name='conservation']").click(); + checkResults("variant-browser-grid"); + }); + + it("4.20 Check gene-view", () => { + cy.get("button[data-id='table-tab']", {timeout: TIMEOUT}).click(); + cy.get("variant-browser-grid .bootstrap-table .fixed-table-container tr[data-index='0'] a.gene-tooltip:first-child") + .should("be.visible", {timeout: TIMEOUT}) + .click({force: true}); + // .trigger('mouseover'); // .trigger('mouseover') doesn't work in this case as the hover action changes the DOM + cy.get(".qtip-content").find("a[data-cy='gene-view']").click({force: true}); + cy.get("div.page-title h2").contains(/Gene [a-z0-9:]+/gim); + }); + + // Variant Browser: Tabs + it("4.21 checks Variant Browser detail tabs", () => { + + cy.get("variant-browser-detail > detail-tabs > div.panel > h3", {timeout: TIMEOUT}).should("contain", "Variant:"); + + cy.get("cellbase-variant-annotation-summary h3").contains("Summary"); + + cy.get("variant-browser-detail [data-id='annotationConsType']").click(); + checkResults("variant-consequence-type-view"); + + cy.get("variant-browser-detail [data-id='annotationPropFreq']").click(); + checkResultsOrNot("cellbase-population-frequency-grid"); + + cy.get("variant-browser-detail [data-id='annotationClinical']").click(); + checkResultsOrNot("variant-annotation-clinical-view"); + + cy.get("variant-browser-detail [data-id='cohortStats']").click(); + checkResults("variant-cohort-stats-grid"); + + cy.get("variant-browser-detail [data-id='samples']").click(); + checkResults("opencga-variant-samples"); + + cy.get("variant-browser-detail [data-id='beacon']").click(); + cy.get("variant-beacon-network", {timeout: TIMEOUT}).find(".beacon-square").its("length").should("eq", 15); + }); + + it("4.22 aggregated query", () => { + + cy.get("opencga-variant-filter a[data-accordion-id='ConsequenceType']").click(); + cy.get("consequence-type-select-filter input[value='Loss-of-Function (LoF)'").click({force: true}); + + cy.get("a[href='#facet_tab']").click({force: true}); + + Facet.selectDefaultFacet(); + // cy.get("button.default-facets-button").click(); // default facets selection (chromosome, type) + + Facet.select("Gene"); + // cy.get("facet-filter .facet-selector li a").contains("Gene").click({force: true}); // gene facets selection + + cy.get("#type_Select a").contains("INSERTION").click({force: true}); // type=INSERTION + Facet.checkActiveFacet("type", "type[INSERTION]"); + // cy.get("div.facet-wrapper button[data-filter-name='type']").contains("type[INSERTION]"); + + Facet.checkActiveFacetLength(3); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(3); + // cy.get("opencb-facet-results", {timeout: 120000}).find("opencga-facet-result-view", {timeout: TIMEOUT}).should("have.lengthOf", 3); // 2 default fields + genes + + Facet.select("Chromosome"); // removing chromosome + Facet.checkActiveFacetLength(2); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(2); + + Facet.removeActive("type"); + Facet.checkResultLength(1); + Facet.removeActive("genes"); + Facet.checkResultLength(0); + + }); +}); diff --git a/cypress/integration/005-opencga-case-portal.spec.js b/cypress/integration/005-opencga-case-portal.spec.js new file mode 100644 index 000000000..659def25b --- /dev/null +++ b/cypress/integration/005-opencga-case-portal.spec.js @@ -0,0 +1,144 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, randomString, checkResults} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("5 - Case Portal", () => { + before(() => { + login(); + }); + + it("5.1 - check query results", () => { + cy.get("a[data-id=clinicalAnalysisPortal]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Case Portal"); + checkResults("opencga-clinical-analysis-grid"); + }); + + it("5.2 - Filter: caseId", () => { + // reading from the first row the case Id, the proband Id, and the Family Id and use them as filters + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(1) a[data-cy='case-id']") + .then($a => { + const caseId = $a.text().trim(); + cy.get("div[data-cy='form-case'] button").click(); + cy.get("div[data-cy='form-case'] input").type(caseId + "{enter}", {force: true}); + checkResults("opencga-clinical-analysis-grid"); + + }); + }); + + it("5.3 - Filter: Proband Sample Id", () => { + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(2) p[data-cy='proband-sample-id']").first() + .then($p => { + const probandSampleId = $p.text().trim(); + console.log("probandSampleId", probandSampleId); + cy.get("div[data-cy='form-sample'] button").click(); + cy.get("div[data-cy='form-sample'] input").type(probandSampleId + "{enter}", {force: true}); + checkResults("opencga-clinical-analysis-grid"); + + }); + }); + + it("5.4 - Filter: Proband Id", () => { + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(2) span[data-cy='proband-id']") + .then($span => { + const probandId = $span.text().trim(); + console.log("probandId", probandId); + cy.get("div[data-cy='form-proband'] button").click(); + cy.get("div[data-cy='form-proband'] input").type(probandId + "{enter}", {force: true}); + checkResults("opencga-clinical-analysis-grid"); + + }); + }); + + it("5.5 - Filter: Disorder name", () => { + // check whether there is a disorder-name, then it tests the filter itself (Cancer studies (type=SINGLE) doesn't have disorder names) + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(4)") + .then($td => { + const span = Cypress.$("span[data-cy='disorder-name']", $td).first(); + const disorderName = span.text().trim(); + console.log("disorderName", disorderName); + cy.get("div[data-cy='form-disorder'] button").click(); + cy.get("div[data-cy='form-disorder'] input").type(disorderName + "{enter}", {force: true}); + checkResults("opencga-clinical-analysis-grid"); + + }); + }); + + it("5.6 - Filter: Family Id", () => { + // check whether there is a family-id, then it tests the filter itself (Cancer studies doesn't have family ids) + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(3)") + .then($td => { + const spans = Cypress.$("span[data-cy='family-id']", $td); + if (spans.length) { + const familyId = spans.first().text().trim(); + // console.log("familyId", familyId); + cy.get("div[data-cy='form-family'] button").click(); + cy.get("div[data-cy='form-family'] input").type(familyId + "{enter}", {force: true}); + checkResults("opencga-clinical-analysis-grid"); + } + }); + }); + + it("5.7 - Filter: Priority Id", () => { + // check whether priority filter is enabled and visible first, then it tests the filter itself + cy.get("div.lhs", {timeout: 5000}).then($wc => { + if (Cypress.$("div[data-cy='form-priority']", $wc).length) { + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}) + .find("td:nth-child(7) span.label").then($span => { + const priority = $span.text().trim(); + // console.error("priority", priority); + cy.get("div[data-cy='form-priority'] button").click(); + cy.get("div[data-cy='form-priority'] ul.dropdown-menu li").contains(priority).click({force: true}); + checkResults("opencga-clinical-analysis-grid"); + }); + } + }); + cy.get("button[data-cy='filter-button']").click({force: true}); + cy.get(".saved-filter-wrapper a").contains("Clear").click({force: true}); + + }); + + + it("5.2 - Columns Visibility", () => { + cy.get("a[data-id=clinicalAnalysisPortal]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Case Portal"); + + + cy.get("opencga-clinical-analysis-grid .columns-toggle-wrapper button").should("be.visible").and("contain", "Columns").click(); + cy.get("opencga-clinical-analysis-grid .columns-toggle-wrapper ul li").should("have.length.gt", 1); + + + cy.get("opencga-clinical-analysis-grid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // deactivate all the columns + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}).find("td", {timeout: TIMEOUT}).should("have.lengthOf", 1); + + cy.get("opencga-clinical-analysis-grid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // reactivate all the columns + cy.get("opencga-clinical-analysis-grid .bootstrap-table .fixed-table-container tr[data-index=0]", {timeout: TIMEOUT}).find("td", {timeout: TIMEOUT}).should("have.length.gt", 1); + + + }); + +}); + +/* cy.get("variant-browser-grid .columns-toggle-wrapper ul li a").each(($li, index, $lis) => { + //Cypress.$("a", $li) +});*/ diff --git a/cypress/integration/006-opencga-case-interpreter.spec.js b/cypress/integration/006-opencga-case-interpreter.spec.js new file mode 100644 index 000000000..2bcd07956 --- /dev/null +++ b/cypress/integration/006-opencga-case-interpreter.spec.js @@ -0,0 +1,127 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, checkResults} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + +const getCaseType = grid => { + checkResults(grid); + return cy.get("opencga-clinical-analysis-grid table tr[data-index=0] td:nth-child(1) p[data-cy='case-type']", {timeout: 60000}).then(type => console.log("TYPE", type)).invoke("text") +}; + + +context("6 - Case Interpreter", () => { + before(() => { + login(); + }); + + it("6.1 - check query results", () => { + let caseId; + + cy.get("a[data-id=clinicalAnalysisPortal]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Case Portal"); + + checkResults("opencga-clinical-analysis-grid"); + + // reading from the first row the case Id, the proband Id, and the Family Id and use them as filters + cy.get("opencga-clinical-analysis-grid table", {timeout: 60000}) + .find("tr[data-index=0]", {timeout: 60000}) + .then($tr => { + const $caseId = Cypress.$("td:nth-child(1) a[data-cy='case-id']", $tr); + const caseId = $caseId.text().trim(); + const caseType = Cypress.$("td:nth-child(1) p[data-cy='case-type']", $tr).text().trim(); + const probandId = Cypress.$("td:nth-child(2) p[data-cy='proband-id']", $tr).text().trim(); + const probandSampleId = Cypress.$("td:nth-child(2) p[data-cy='proband-sample-id']", $tr).text().trim(); + cy.wrap($caseId).click(); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Case Interpreter Case " + caseId); + + // test Case Interpreter in Family Cases + console.log("caseType === \"FAMILY\"", caseType === "FAMILY") + if (caseType === "FAMILY") { + + /** + * Overview test + */ + cy.get(".variant-interpreter-wizard a.variant-interpreter-step").contains("Case Info").click(); + // check Case ID in Overview + cy.get("opencga-clinical-analysis-view > data-form .detail-row:nth-child(1)").contains("Case ID"); + cy.get("opencga-clinical-analysis-view > data-form .detail-row:nth-child(1)").then($div => { + expect($div.first().text()).to.include(caseId); + }); + // check Case Type in Overview + cy.get("opencga-clinical-analysis-view > data-form .detail-row:nth-child(4)").contains("Analysis Type"); + cy.get("opencga-clinical-analysis-view > data-form .detail-row:nth-child(4)").then($div => { + expect($div.first().text()).to.include("FAMILY"); + }); + + + /** + * Quality control test + */ + cy.get(".variant-interpreter-wizard a.variant-interpreter-step").contains("Quality Control").click(); + // Default tab in Quality Control is Overview + cy.get("variant-interpreter-qc .content-tab-wrapper .content-tab.active .page-title h2").contains("Quality Control Overview - " + caseId); + + // click on Quality Control/Sample Variant Stats + cy.get("variant-interpreter-qc .nav-tabs a[data-id=SampleVariantStats]").click(); + cy.get("variant-interpreter-qc .content-tab-wrapper .content-tab.active .page-title h2").contains(`Sample Variant Stats - ${caseId} (${probandSampleId})`); + // checks there are 9 charts + cy.get("sample-variant-stats-view simple-chart").should("be.visible").and("have.length", 9); + + // select PASS filter + cy.get("opencga-variant-filter file-quality-filter input[data-cy='filter-pass']").click(); + cy.get("opencga-active-filters button[data-filter-name='filter']").contains("FILTER = PASS"); + cy.get("div.search-button-wrapper button").click(); + + cy.wait(1000); + cy.get("sample-variant-stats-browser loading-spinner", {timeout: 120000}).should("not.exist"); + // checks there are 9 charts after the search + cy.get("sample-variant-stats-view simple-chart").should("be.visible").and("have.length", 9); + + /** + * Sample Variant Browser test + */ + cy.get(".variant-interpreter-wizard a.variant-interpreter-step").contains("Sample Variant Browser").click(); + checkResults("variant-interpreter-grid"); + + cy.get("opencga-active-filters button[data-filter-name='sample']").contains("Sample Genotype"); + cy.get("opencga-variant-filter file-quality-filter input[data-cy='filter-pass']").click(); + cy.get("opencga-active-filters button[data-filter-name='filter']").contains("FILTER = PASS"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-interpreter-grid"); + + // check Disease Panel select is actually populated (but not querying for Diseases) + cy.get("a[data-accordion-id=Clinical].collapsed").click(); + cy.get("disease-panel-filter").should("be.visible"); + cy.get("disease-panel-filter button").click(); + cy.get("disease-panel-filter select-field-filter ul.dropdown-menu li").should("have.length.above", 0); + cy.get("disease-panel-filter button").click(); + + // query LoF + cy.get("opencga-variant-filter a[data-accordion-id='ConsequenceType'].collapsed").click(); + cy.get("consequence-type-select-filter input[value='Loss-of-Function (LoF)'").click({force: true}); + cy.get("opencga-active-filters button[data-filter-name='ct']").contains("Consequence Types"); + cy.get("div.search-button-wrapper button").click(); + checkResults("variant-interpreter-grid"); + } + + }); + + + }); + + +}); diff --git a/cypress/integration/007-opencga-sample-browser.spec.js b/cypress/integration/007-opencga-sample-browser.spec.js new file mode 100644 index 000000000..f1d79f49f --- /dev/null +++ b/cypress/integration/007-opencga-sample-browser.spec.js @@ -0,0 +1,88 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, checkResults, changePage, getResult, Facet, dateFilterCheck, annotationFilterCheck} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("7 - Sample Browser", () => { + before(() => { + login(); + }); + + it("7.1 - query", () => { + cy.get("a[data-id=sample]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Sample Browser"); + + checkResults("opencga-sample-grid"); + getResult("opencga-sample-grid").then($text => { + cy.get("sample-id-autocomplete input").type($text + "{enter}"); + }); + + cy.get(".lhs button[data-filter-name]").should("have.length", 1); + cy.get("div.search-button-wrapper button").click(); + checkResults("opencga-sample-grid"); + + cy.get("#somatic + .subsection-content label").contains("True").click({force: true}); // setting filter Somatic = true + + cy.get("opencga-active-filters button[data-filter-name='id']").click(); + cy.get("opencga-active-filters button[data-filter-name='somatic']").click(); + cy.get(".lhs button[data-filter-name]").should("have.length", 0); + + checkResults("opencga-sample-grid"); + changePage("opencga-sample-grid", 2); + checkResults("opencga-sample-grid"); + changePage("opencga-sample-grid", 1); + checkResults("opencga-sample-grid"); + + dateFilterCheck("opencga-sample-grid"); + + annotationFilterCheck("opencga-sample-grid"); + + }); + it("7.2 - aggregated query", () => { + cy.get("a[data-id=sample]").click({force: true}); + cy.get("a[href='#facet_tab']").click({force: true}); + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "status", "phenotypes", "somatic" + // cy.get("button.default-facets-button").click(); // "creationYear>>creationMonth", "status", "phenotypes", "somatic" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + Facet.checkActiveFacet("status", "status"); + Facet.checkActiveFacet("somatic", "somatic"); + + + Facet.checkActiveFacetLength(3); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(3); + + // cy.get("div.facet-wrapper button[data-filter-name='creationYear']").contains("creationYear>>creationMonth"); + + cy.get("[data-id='status'] ul.dropdown-menu a").contains("READY").click({force: true}); // status=READY + Facet.checkActiveFacet("status", "status[READY]"); + // cy.get("div.facet-wrapper button[data-filter-name='status']").contains("status[READY]"); + + + cy.get("[data-id='somatic'] ul.dropdown-menu a").contains("true").click({force: true}); // somatic=true + Facet.checkActiveFacet("somatic", "somatic[true]"); + + Facet.select("Status"); // removing status + + Facet.checkActiveFacetLength(2); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(2); + }); +}); diff --git a/cypress/integration/008-opencga-individual-browser.spec.js b/cypress/integration/008-opencga-individual-browser.spec.js new file mode 100644 index 000000000..c0de60e99 --- /dev/null +++ b/cypress/integration/008-opencga-individual-browser.spec.js @@ -0,0 +1,108 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, checkResults, getResult, Facet, changePage, dateFilterCheck, annotationFilterCheck, checkExactResult} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("8 - Individual Browser", () => { + before(() => { + login(); + }); + + it("8.1 - query", () => { + cy.get("a[data-id=individual]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Individual Browser"); + + checkResults("opencga-individual-grid"); + changePage("opencga-individual-grid", 2); + checkResults("opencga-individual-grid"); + changePage("opencga-individual-grid", 1); + checkResults("opencga-individual-grid"); + + getResult("opencga-individual-grid", 1).then($text => { + cy.get("individual-id-autocomplete input").first().type($text + "{enter}"); + cy.get("div.search-button-wrapper button").click(); + checkExactResult("opencga-individual-grid", 1); + cy.get("opencga-active-filters button[data-filter-name='id']").click(); + checkResults("opencga-individual-grid"); + }); + + // sort id ASC + cy.get("opencga-individual-grid table .th-inner.sortable").contains("Individual").click(); + checkResults("opencga-individual-grid"); + getResult("opencga-individual-grid", 1, 0).then($ind1 => { + getResult("opencga-individual-grid", 1, 1).then($ind2 => { + getResult("opencga-individual-grid", 1, 2).then($ind3 => { + const sorted = [$ind1, $ind2, $ind3]; + sorted.sort(); + expect(JSON.stringify([$ind1, $ind2, $ind3]), "Individuals are sorted").to.be.equal(JSON.stringify(sorted)); + // TODO this fails + // expect([$ind1, $ind3, $ind2], "Individuals are sorted").to.deep.equal(sorted); + }); + }); + }); + + dateFilterCheck("opencga-individual-grid"); + annotationFilterCheck("opencga-individual-grid"); + + + }); + + + it("8.2 - aggregated query", () => { + cy.get("a[data-id=individual]").click({force: true}); + cy.get("a[href='#facet_tab']").click({force: true}); + + cy.get("button.default-facets-button").click(); + cy.get("div.search-button-wrapper button").click(); + cy.get(".facet-wrapper .button-list button").should("have.length", 8); + cy.get("opencb-facet-results opencga-facet-result-view", {timeout: TIMEOUT}).should("have.length", 8); + + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "status", "ethnicity", "population", "lifeStatus", "phenotypes", "sex", "numSamples[0..10]:1" + // cy.get("button.default-facets-button").click(); // "creationYear>>creationMonth", "status", "phenotypes", "somatic" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + Facet.checkActiveFacet("status", "status"); + Facet.checkActiveFacet("ethnicity", "ethnicity"); + Facet.checkActiveFacet("population", "population"); + Facet.checkActiveFacet("lifeStatus", "lifeStatus"); + Facet.checkActiveFacet("phenotypes", "phenotypes"); + Facet.checkActiveFacet("sex", "sex"); + Facet.checkActiveFacet("numSamples", "numSamples[0..10]:1"); + + + Facet.checkActiveFacetLength(8); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(8); + + // cy.get("div.facet-wrapper button[data-filter-name='creationYear']").contains("creationYear>>creationMonth"); + + cy.get("[data-id='status'] ul.dropdown-menu a").contains("READY").click({force: true}); // status=READY + Facet.checkActiveFacet("status", "status[READY]"); + // cy.get("div.facet-wrapper button[data-filter-name='status']").contains("status[READY]"); + + + Facet.select("Status"); // removing status + + Facet.checkActiveFacetLength(7); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(7); + + }); + +}); diff --git a/cypress/integration/009-opencga-family-browser.spec.js b/cypress/integration/009-opencga-family-browser.spec.js new file mode 100644 index 000000000..ac3934eb1 --- /dev/null +++ b/cypress/integration/009-opencga-family-browser.spec.js @@ -0,0 +1,118 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {checkResults, login, getResult, checkResultsOrNot, hasResults, Facet, changePage, dateFilterCheck, annotationFilterCheck} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("9 - Family Browser", () => { + before(() => { + login(); + }); + + it("9.1 - query", () => { + cy.get("a[data-id=family]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Family Browser"); + + checkResultsOrNot("opencga-family-grid"); + + hasResults("opencga-family-grid").then($bool => { + if ($bool) { + // run other tests in case there are results + getResult("opencga-family-grid", 1).then($text => { + cy.get("family-id-autocomplete input").type($text + "{enter}"); + cy.get(".lhs button[data-filter-name]").should("have.length", 1); + cy.get("div.search-button-wrapper button").click(); + }); + checkResults("opencga-family-grid"); + cy.get("opencga-active-filters button[data-filter-name='id']").click(); + + checkResults("opencga-family-grid"); + getResult("opencga-family-grid", 3, 0, "html").then($html => { + cy.wrap($html).get("span[data-cy]").then($text => { + cy.get(".subsection-content[data-cy=disorders] input").type($text.first().text() + "{enter}"); + cy.get("div.search-button-wrapper button").click(); + checkResults("opencga-family-grid"); + cy.get("opencga-active-filters button[data-filter-name='disorders']").click(); + }); + }); + checkResults("opencga-family-grid"); + changePage("opencga-family-grid", 2); + checkResults("opencga-family-grid"); + changePage("opencga-family-grid", 1); + checkResults("opencga-family-grid"); + + // sort id ASC + cy.get("opencga-family-grid table .th-inner.sortable").contains("Family").click(); + checkResults("opencga-family-grid"); + getResult("opencga-family-grid", 1, 0).then($f1 => { + getResult("opencga-family-grid", 1, 1).then($f2 => { + getResult("opencga-family-grid", 1, 2).then($f3 => { + const sorted = [$f1, $f2, $f3]; + sorted.sort(); + expect(JSON.stringify([$f1, $f2, $f3]), "Families are sorted").to.be.equal(JSON.stringify(sorted)); + // TODO this fails + // expect([$f1, $f2, $f3], "Families are sorted").to.deep.equal(sorted); + }); + }); + }); + + dateFilterCheck("opencga-family-grid"); + annotationFilterCheck("opencga-family-grid"); + } + }); + }); + + it("9.2 - aggregated query", () => { + cy.get("a[data-id=family]").click({force: true}); + cy.get("a[data-id=family]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Family Browser"); + + checkResultsOrNot("opencga-family-grid"); + + hasResults("opencga-family-grid").then($bool => { + if ($bool) { + // in case there are actually results, run the aggregated tests + cy.get("a[href='#facet_tab']").click({force: true}); + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "status", "phenotypes", "expectedSize", "numMembers[0..20]:2" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + Facet.checkActiveFacet("status", "status"); + Facet.checkActiveFacet("phenotypes", "phenotypes"); + Facet.checkActiveFacet("expectedSize", "expectedSize"); + Facet.checkActiveFacet("numMembers", "numMembers[0..20]:2"); + + + Facet.checkActiveFacetLength(5); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(5); + + cy.get("[data-id='status'] ul.dropdown-menu a").contains("READY").click({force: true}); // status=READY + Facet.checkActiveFacet("status", "status[READY]"); + + Facet.select("Status"); // removing status + Facet.select("Expected Size"); // removing status + + Facet.checkActiveFacetLength(3); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(3); + + } + }); + + }); +}); diff --git a/cypress/integration/010-opencga-file-browser.spec.js b/cypress/integration/010-opencga-file-browser.spec.js new file mode 100644 index 000000000..7e9ed86c0 --- /dev/null +++ b/cypress/integration/010-opencga-file-browser.spec.js @@ -0,0 +1,122 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, getResult, checkResults, Facet, changePage, dateFilterCheck, annotationFilterCheck} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("10 - File Browser", () => { + before(() => { + login(); + }); + + it("10.1 - query", () => { + cy.get("a[data-id=file]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "File Browser"); + + checkResults("opencga-file-grid"); + + getResult("opencga-file-grid").then($text => { + cy.get("file-name-autocomplete input").type($text + "{enter}"); + }); + + cy.get(".lhs button[data-filter-name]").should("have.length", 1); + + cy.get("div.search-button-wrapper button").click(); + checkResults("opencga-file-grid"); + + cy.get("#format + .subsection-content a").contains("VCF").click({force: true}); + cy.get("#bioformat + .subsection-content a").contains("VARIANT").click({force: true}); + + cy.get(".lhs button[data-filter-name]").should("have.length", 3); + cy.get("div.search-button-wrapper button").click(); + + checkResults("opencga-file-grid"); + changePage("opencga-file-grid", 2); + checkResults("opencga-file-grid"); + changePage("opencga-file-grid", 1); + checkResults("opencga-file-grid"); + + dateFilterCheck("opencga-file-grid"); + annotationFilterCheck("opencga-file-grid"); + + + }); + + it("10.2 - aggregated query", () => { + cy.get("a[data-id=file]").click({force: true}); + cy.get("a[href='#facet_tab']").click({force: true}); + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "bioformat", "format>>bioformat", "status", "size[0..214748364800]:10737418240", "numSamples[0..10]:1" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + // cy.get("div.facet-wrapper button[data-filter-name='creationYear']").contains("creationYear>>creationMonth"); + + Facet.checkActiveFacet("format", "format>>bioformat"); + //cy.get("div.facet-wrapper button[data-filter-name='format']").contains("format>>bioformat"); + + Facet.checkActiveFacet("bioformat", "bioformat"); + //cy.get("div.facet-wrapper button[data-filter-name='bioformat']").contains("bioformat"); + + Facet.checkActiveFacet("status", "status"); + //cy.get("div.facet-wrapper button[data-filter-name='status']").contains("status"); + + Facet.checkActiveFacet("size", "size[0..214748364800]:10737418240"); + //cy.get("div.facet-wrapper button[data-filter-name='size']").contains("size[0..214748364800]:10737418240"); + + Facet.checkActiveFacet("numSamples", "numSamples[0..10]:1"); + //cy.get("div.facet-wrapper button[data-filter-name='numSamples']").contains("numSamples[0..10]:1"); + + + cy.get("[data-id='status'] ul.dropdown-menu a").contains("READY").click({force: true}); // status=READY + Facet.checkActiveFacet("status", "status[READY]"); + // cy.get("div.facet-wrapper button[data-filter-name='status']").contains("status[READY]"); + + cy.get("div.search-button-wrapper button").click(); + + Facet.checkActiveFacetLength(6); + Facet.checkResultLength(6); + //cy.get("div.facet-wrapper button[data-filter-value]", {timeout: TIMEOUT}).should("have.length", 6); + //cy.get("opencb-facet-results opencga-facet-result-view", {timeout: TIMEOUT}).should("have.length", 6); + + + Facet.select("Creation Year"); // removing Creation Year + //cy.get("facet-filter .facet-selector li a").contains("Creation Year").click({force: true}); // creationYear remove + + Facet.checkActiveFacetLength(5); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(5); + + //cy.get("div.facet-wrapper button[data-filter-value]", {timeout: TIMEOUT}).should("have.length", 5); + //cy.get("div.search-button-wrapper button").click(); + //cy.get("opencb-facet-results opencga-facet-result-view", {timeout: TIMEOUT}).should("have.length", 5); + + Facet.select("Creation Year"); // adding Creation Year + cy.get("a[data-collapse=\"#creationYear_nested\"]").click({force: true}); + cy.get("#creationYear_nested select-field-filter div.dropdown-menu a").contains("Creation Month").click({force: true}); // Creation Month nested in Year field + + // removing all values but `creationYear` and `format` through the select, not active-filter + Facet.select("Bioformat"); + Facet.select("Status"); + Facet.select("Size"); + Facet.select("Number Of Samples"); + + Facet.checkActiveFacetLength(2); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(2); + + }); +}); diff --git a/cypress/integration/011-opencga-cohort-browser.spec.js b/cypress/integration/011-opencga-cohort-browser.spec.js new file mode 100644 index 000000000..602be90d0 --- /dev/null +++ b/cypress/integration/011-opencga-cohort-browser.spec.js @@ -0,0 +1,78 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {checkResults, login, getResult, Facet, changePage, dateFilterCheck, annotationFilterCheck} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("11 - Cohort Browser", () => { + before(() => { + login(); + }); + + it("11.1 - query", () => { + cy.get("a[data-id=cohort]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Cohort Browser"); + checkResults("opencga-cohort-grid"); + + getResult("opencga-cohort-grid").then($text => { + cy.get("cohort-id-autocomplete input").type($text + "{enter}"); + }); + cy.get(".lhs button[data-filter-name]").should("have.length", 1); + + cy.get("div.search-button-wrapper button").click(); + + checkResults("opencga-cohort-grid"); + changePage("opencga-cohort-grid", 2); + checkResults("opencga-cohort-grid"); + changePage("opencga-cohort-grid", 1); + checkResults("opencga-cohort-grid"); + + dateFilterCheck("opencga-cohort-grid"); + annotationFilterCheck("opencga-cohort-grid"); + + }); + + it("11.2 - aggregated query", () => { + cy.get("a[data-id=cohort]").click({force: true}); + + cy.get("a[href='#facet_tab']").click({force: true}); + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "status", "numSamples[0..10]:1" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + Facet.checkActiveFacet("status", "status"); + Facet.checkActiveFacet("numSamples", "numSamples[0..10]:1"); + + + Facet.checkActiveFacetLength(3); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(3); + + // cy.get("div.facet-wrapper button[data-filter-name='creationYear']").contains("creationYear>>creationMonth"); + + cy.get("[data-id='status'] ul.dropdown-menu a").contains("READY").click({force: true}); // status=READY + Facet.checkActiveFacet("status", "status[READY]"); + + Facet.select("Status"); // removing status + + Facet.checkActiveFacetLength(2); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(2); + + + }); +}); diff --git a/cypress/integration/012-opencga-jobs-browser.spec.js b/cypress/integration/012-opencga-jobs-browser.spec.js new file mode 100644 index 000000000..a6ffc6aca --- /dev/null +++ b/cypress/integration/012-opencga-jobs-browser.spec.js @@ -0,0 +1,81 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, getResult, checkResults, Facet, changePage, dateFilterCheck, annotationFilterCheck} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("12 - Jobs Browser", () => { + before(() => { + login(); + }); + + it("12.1 - query", () => { + cy.get("a[data-id=job]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Jobs Browser"); + + checkResults("opencga-job-grid"); + + getResult("opencga-job-grid", 1).then($text => { + cy.get("jobs-id-autocomplete input").type($text + "{enter}"); + }); + getResult("opencga-job-grid", 2).then($text => { + cy.get("analysis-tool-id-autocomplete input").type($text + "{enter}"); + }); + + cy.get(".lhs button[data-filter-name]").should("have.length", 2); + + cy.get("div.search-button-wrapper button").click(); + checkResults("opencga-job-grid"); + + cy.get("#priority + .subsection-content a").click({force: true, multiple: true}); + + cy.get(".lhs button[data-filter-name]").should("have.length", 3); + cy.get("div.search-button-wrapper button").click(); + + checkResults("opencga-job-grid"); + changePage("opencga-job-grid", 2); + checkResults("opencga-job-grid"); + changePage("opencga-job-grid", 1); + checkResults("opencga-job-grid"); + + dateFilterCheck("opencga-job-grid"); + annotationFilterCheck("opencga-job-grid"); + + }); + + it("12.1 - aggregated query", () => { + cy.get("a[data-id=job]").click({force: true}); + cy.get("a[href='#facet_tab']").click({force: true}); + + + Facet.selectDefaultFacet(); // "creationYear>>creationMonth", "toolId>>executorId" + + Facet.checkActiveFacet("creationYear", "creationYear>>creationMonth"); + Facet.checkActiveFacet("toolId", "toolId>>executorId"); + + Facet.checkActiveFacetLength(2); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(2); + + Facet.select("Tool Id"); // removing toolId + + Facet.checkActiveFacetLength(1); + cy.get("div.search-button-wrapper button").click(); + Facet.checkResultLength(1); + + }); +}); diff --git a/cypress/integration/013-welcome.spec.js b/cypress/integration/013-welcome.spec.js new file mode 100644 index 000000000..ca6bf9ad2 --- /dev/null +++ b/cypress/integration/013-welcome.spec.js @@ -0,0 +1,51 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +const resolveButtons = page => { + cy.get(".login-overlay", {timeout: TIMEOUT}).should("not.exist"); + cy.get(`a[data-cat-id=${page.id}]`).should("be.visible").click(); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", page.title); + cy.get("a#home-nav").click(); +}; + +context("13 - Welcome page", () => { + before(() => { + login(); + }); + + it("13.1 - check home page content", () => { + cy.get("#home-nav > img", {timeout: TIMEOUT}).should("be.visible"); + cy.get("a#home-nav").click(); + cy.get(".login-overlay", {timeout: TIMEOUT}).should("not.exist"); + cy.get("#welcome-page-title", {timeout: TIMEOUT}).contains("Interactive Variant Analysis"); + cy.get(".iva-logo").find("img").should("be.visible"); + cy.get("#welcome-page-title ").contains("Interactive Variant Analysis"); + }); + + it("13.2 - check buttons resolves correctly", () => { + + cy.get(".hi-icon-animation > a").each(el => { + const id = el.data("cat-id"); + const title = el.data("title"); + resolveButtons({id, title}); + }); + }); + +}); diff --git a/cypress/integration/014-rga-browser.spec.js b/cypress/integration/014-rga-browser.spec.js new file mode 100644 index 000000000..157c98543 --- /dev/null +++ b/cypress/integration/014-rga-browser.spec.js @@ -0,0 +1,227 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, getResult, checkResults, checkResultsOrNot} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("14 - RGA Browser", () => { + before(() => { + login(); + }); + /* "geneName", + "IndividualId", + "numParents", + "cohort", + "populationFrequencyAlt", + "type", + "consequenceType", + "clinicalSignificance"*/ + it("14.1 - Gene View", () => { + cy.get("a[data-id=rga]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Recessive Variant Browser"); + cy.get("button[data-tab-id='gene-tab']", {timeout: TIMEOUT}).click({force: true}); + + cy.get("rga-gene-view .columns-toggle-wrapper button").should("be.visible").and("contain", "Columns").click(); + cy.get("rga-gene-view .columns-toggle-wrapper ul li").and("have.length.gt", 1); + + cy.get("rga-gene-view .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // deactivate all the columns + cy.get("rga-gene-view .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.lengthOf", 0); + + cy.get("rga-gene-view .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // reactivate all the columns + cy.get("rga-gene-view .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.length.gt", 1); + + checkResults("rga-gene-view"); + + // gene Name + // queries for the first gene and then check if the first result contains the gene. + let geneName; + getResult("rga-gene-view", 0).then($text => { + geneName = $text; + cy.get("feature-filter input[type='text']").type(geneName); + cy.get("feature-filter ul.dropdown-menu li").should("have.lengthOf", 1); + + // occasionally fails + // Timed out retrying after 4050ms: cy.click() failed because this element is detached from the DOM. + // DMKN + cy.wait(500); + cy.get("feature-filter ul.dropdown-menu li.active a").click({force: true}); + cy.get("div.search-button-wrapper button").click(); + + checkResults("rga-gene-view"); + getResult("rga-gene-view", 0).then($resultCell => { + cy.wrap($resultCell).should("contain", geneName); + + }); + }); + + // knockoutType + cy.get("section-filter#Gene div[data-cy='knockoutType'] button").click(); + cy.get("section-filter#Gene div[data-cy='knockoutType'] .dropdown-menu a").contains("COMP_HET").click(); + cy.get("div.search-button-wrapper button").click(); + checkResults("rga-gene-view"); + + // set numParents=2 + cy.get("section-filter#Confidence .magic-checkbox-wrapper > :nth-child(3) > label").click(); + cy.get("div.search-button-wrapper button").click(); + checkResults("rga-gene-view"); + + // checking the number of CH Definite is > 0 (the current query is geneName=XXX,knockoutType=COMP_HET,numParents=2) + getResult("rga-gene-view", 3).then($CHDefiniteNum => { + // expect($div.text().trim()).gt(0) + assert.isAbove(Number($CHDefiniteNum), 0, "Results"); + }); + + // cy.get("opencga-active-filters button[data-filter-name='knockoutType']").click(); + + cy.get("button.active-filter-label").click(); + cy.get("a[data-action='active-filter-clear']").click(); + checkResults("rga-gene-view"); + + }); + it("14.2 - Individual View", () => { + cy.get("a[data-id=rga]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Recessive Variant Browser"); + cy.get("button[data-tab-id='individual-tab']", {timeout: TIMEOUT}).click({force: true}); + + checkResults("rga-individual-view"); + + cy.get("rga-individual-view .columns-toggle-wrapper button").should("be.visible").and("contain", "Columns").click(); + cy.get("rga-individual-view .columns-toggle-wrapper ul li").and("have.length.gt", 1); + + cy.get("rga-individual-view .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // deactivate all the columns + cy.get("rga-individual-view .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.lengthOf", 1); + + cy.get("rga-individual-view .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // reactivate all the columns + cy.get("rga-individual-view .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.length.gt", 1); + + // queries for the first gene and then check if the first result contains the gene. + let IndividualId; + getResult("rga-individual-view", 0).then($text => { + IndividualId = $text; + console.log("IndividualId i", IndividualId); + cy.get("div[data-cy='individualId'] input[type='text']").type(IndividualId + "{enter}"); + cy.get("div.search-button-wrapper button").click(); + checkResults("rga-individual-view"); + + getResult("rga-individual-view", 0).then($resultCell => { + console.log("$resultCell", $resultCell); + cy.wrap($resultCell).should("contain", IndividualId); + + }); + + // check detail-tabs family table + // ensure `IndividualId` is present in table header + cy.get("rga-individual-family table > thead > :nth-child(1) > :nth-child(7) > .th-inner").contains(IndividualId); + + }); + cy.get("button.active-filter-label").click(); + cy.get("a[data-action='active-filter-clear']").click(); + checkResults("rga-individual-view"); + + }); + it("14.3 - Variant View", () => { + cy.get("a[data-id=rga]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Recessive Variant Browser"); + cy.get("button[data-tab-id='variant-tab']", {timeout: TIMEOUT}).click({force: true}); + + checkResults("rga-variant-view"); + + cy.get("rga-variant-view > .container-fluid .columns-toggle-wrapper button").should("be.visible").and("contain", "Columns").click(); + cy.get("rga-variant-view > .container-fluid .columns-toggle-wrapper ul li").and("have.length.gt", 1); + + cy.get("rga-variant-view > .container-fluid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // deactivate all the columns + cy.get("rga-variant-view > .container-fluid > .row .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.lengthOf", 0); + + cy.get("rga-variant-view > .container-fluid .columns-toggle-wrapper ul li a").click({multiple: true, timeout: TIMEOUT}); // reactivate all the columns + cy.get("rga-variant-view > .container-fluid > .row .bootstrap-table .fixed-table-container tr[data-index=0] > td", {timeout: TIMEOUT}).should("have.length.gt", 1); + + cy.get("button.active-filter-label").click(); + cy.get("a[data-action='active-filter-clear']").click(); + + checkResults("rga-variant-view"); + + let variantId; + // region + getResult("rga-variant-view", 0).then(vId => { + variantId = vId; + const region = variantId.trim().match(/\d+:\d+/)[0]; + cy.get("region-filter textarea").type(region); + cy.get("div.search-button-wrapper button").click(); + checkResults("rga-variant-view"); + getResult("rga-variant-view", 0).then($resultCell => { + cy.wrap($resultCell).should("contain", region); + + }); + }); + + cy.get("opencga-active-filters button[data-filter-name='region']").click(); + checkResults("rga-variant-view"); + + // gene Name + // queries for the first gene and then check if the first result contains the gene. + let geneName; + getResult("rga-variant-view", 1).then($text => { + geneName = $text.split(",")[0]; + cy.get("feature-filter input[type='text']").type(geneName); + cy.get("feature-filter ul.dropdown-menu li").should("have.lengthOf", 1); + + // occasionally fails + // Timed out retrying after 4050ms: cy.click() failed because this element is detached from the DOM. + // DMKN + cy.wait(500); + cy.get("feature-filter ul.dropdown-menu li.active a").click({force: true}); + cy.get("div.search-button-wrapper button").click(); + + checkResults("rga-variant-view"); + getResult("rga-variant-view", 1).then($resultCell => { + cy.wrap($resultCell).should("contain", geneName); + }); + }); + + cy.get("opencga-active-filters button[data-filter-name='geneName']").click(); + checkResults("rga-variant-view"); + + // detail-tabs allele pairs table + cy.get("rga-variant-view detail-tabs ul.nav-tabs > li > a").contains("Allele Pairs").click(); + checkResults("rga-variant-allele-pairs"); + getResult("rga-variant-allele-pairs", 0).then($resultCell => { + // check the variant id stored before + cy.wrap($resultCell).should("contain", variantId); + }); + + // detail-tabs Individuals table + // 1. get the first individual out of Individual View + // 2. use it to filter Variant View + // 3. check individual to be present in variant-individual-grid + cy.get("button[data-tab-id='individual-tab']", {timeout: TIMEOUT}).click({force: true}); + checkResults("rga-individual-view"); + let IndividualId; + getResult("rga-individual-view", 0).then($text => { + IndividualId = $text; + cy.get("button[data-tab-id='variant-tab']", {timeout: TIMEOUT}).click({force: true}); + checkResults("rga-variant-view"); + cy.get("div[data-cy='individualId'] input[type='text']").type(IndividualId + "{enter}"); + cy.get("div.search-button-wrapper button").click(); + checkResults("rga-variant-view"); + + checkResults("rga-variant-individual-grid"); + getResult("rga-variant-individual-grid", 0).then($resultCell => { + cy.wrap($resultCell).should("contain", IndividualId); + }); + }); + }); +}); diff --git a/cypress/integration/OPENCGA-924.spec.js b/cypress/integration/OPENCGA-924.spec.js new file mode 100644 index 000000000..a23574cd2 --- /dev/null +++ b/cypress/integration/OPENCGA-924.spec.js @@ -0,0 +1,41 @@ +/** + * Copyright 2015-2016 OpenCB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {login, checkResults, getResult} from "../plugins/utils.js"; +import {TIMEOUT} from "../plugins/constants.js"; + + +context("7 - Sample Browser", () => { + before(() => { + login(); + }); + + it("7.1 - query", () => { + cy.get("a[data-id=sample]", {timeout: TIMEOUT}).click({force: true}); + cy.get("div.page-title h2", {timeout: TIMEOUT}).should("be.visible").and("contain", "Sample Browser"); + + // checkResults("opencga-sample-grid"); + + cy.get("sample-id-autocomplete input").invoke("val", "LP3000045-DNA_B04"); + cy.get("sample-id-autocomplete input").type("{enter}"); + + cy.get("div.search-button-wrapper button").click(); + + //cy.get("opencga-active-filters button[data-filter-name='id']").click(); + + + }); +}); diff --git a/cypress/integration/login.js b/cypress/integration/login.js deleted file mode 100644 index a66f41a88..000000000 --- a/cypress/integration/login.js +++ /dev/null @@ -1,31 +0,0 @@ -context("Login", () => { - beforeEach(() => { - cy.visit("http://localhost:3000/src/#login") - }) - - it("login unsuccessful", () => { - cy.get("#opencgaUser").type("demo") - cy.get("#opencgaPassword").type("demo") - cy.get("form#formLogin").submit() - - cy.get("#error").contains( "Incorrect user or password.") - }) - - it("login uccessful", () => { - - const username = Cypress.env("username") - const password = Cypress.env("password") - - //console.log("username", username) - //console.log("password", password) - - expect(username, "username was set").to.be.a("string").and.not.be.empty - expect(password, "password was set").to.be.a("string").and.not.be.empty - cy.get("#opencgaUser").type(username) - cy.get("#opencgaPassword").type(password) - cy.get("form#formLogin").submit() - - cy.url().should("include", "#home") - cy.get(".subtitle").contains( "Interactive Variant Analysis") - }) -}) diff --git a/cypress/integration/opencga-clinical-portal.spec.js b/cypress/integration/opencga-clinical-portal.spec.js deleted file mode 100644 index 4a74456da..000000000 --- a/cypress/integration/opencga-clinical-portal.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import {login} from "../plugins/utils.js"; -import "cypress-wait-until"; - -context("Case Portal", () => { - before(() => { - login(); - }) - - it("query", () => { - /*cy.waitUntil(() => cy.getCookie("iva_sid").then(cookie => { - console.log("cookie", cookie) - return Boolean(cookie && cookie.value) - }));*/ - - cy.get("a[data-id=clinicalAnalysisPortal]").click({force: true}) - - //long timeout to make sure you are logged in - cy.get("div.page-title h2", {timeout: 60000}).should("be.visible").and("contain", "Case Portal") - - //cy.get(".lhs button").should("have.length", 2) - cy.get(".clearfix > .pull-left > .pagination-info", {timeout: 10000}) - .should("be.visible") - //.should('contain', /Showing \d+ to \d+ of \d+ records/) - //.and("contain", "Showing 1 to 10 of 18 records") - - - cy.get("opencga-clinical-analysis-grid .success > :nth-child(1)").then(elem => { - // elem is the underlying Javascript object targeted by the .get() command. - const firstCase = Cypress.$(elem).text().trim(); - //opencga-clinical-analysis-view > data-form div:nth-child(1) > div.col-md-9 - }); - - }) -}) diff --git a/cypress/integration/opencga-file-browser.spec.js b/cypress/integration/opencga-file-browser.spec.js deleted file mode 100644 index e21da461a..000000000 --- a/cypress/integration/opencga-file-browser.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import {login} from "../plugins/utils.js"; - -context("File Browser", () => { - before(() => { - login(); - }) - - it("query", () => { - cy.get("a[data-id=files]").click({force: true}) - cy.get("div.page-title h2", {timeout: 60000}).should("be.visible").and("contain", "File Browser") - - cy.get("#format + .subsection-content a").contains( "VCF").click({force: true}) - cy.get("#bioformat + .subsection-content a").contains( "VARIANT").click({force: true}) - - cy.get(".lhs button[data-filter-name]").should("have.length", 2) - - //cy.get('.fixed-table-toolbar').find(".pagination-info", {log:true}) - cy.get("div.search-button-wrapper button").click() - }) - - it("aggregated query", () => { - cy.get("a[data-id=files]").click({force: true}) - cy.get("a[href='#facet_tab']").click({force: true}) - //cy.get("div.search-button-wrapper button").click() - - //cy.wait(2000); - - cy.get("#bs-select-4-2").click({force: true}) // creation year field - cy.get(`a[data-collapse="#creationYear_nested"]`).click({force: true}) // creation y field - cy.get("#bs-select-7-3").click({force: true}) // creation month nested in year field - cy.get("div.search-button-wrapper button").click() - - }) -}) diff --git a/cypress/integration/opencga-individual-browser.spec.js b/cypress/integration/opencga-individual-browser.spec.js deleted file mode 100644 index a746f077a..000000000 --- a/cypress/integration/opencga-individual-browser.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import {login} from "../plugins/utils.js"; - -context("Individual Browser", () => { - before(() => { - login(); - }) - - it("query", () => { - cy.get("a[data-id=individuals]").click({force: true}) - cy.get("div.page-title h2", {timeout: 60000}).should("be.visible").and("contain", "Individual Browser") - - cy.get("#sex + .subsection-content a").contains( "MALE").click({force: true}) - cy.get("#sex + .subsection-content a").contains( "FEMALE").click({force: true}) - - cy.get("#date + .subsection-content input[data-tab=recent] + label").click(); //creationDate recent - - cy.get(".lhs button[data-filter-name]").should("have.length", 2); - cy.get("div.search-button-wrapper button").click(); - - }) - - it("aggregated query", () => { - cy.get("a[data-id=individuals]").click({force: true}) - - cy.get("a[href='#facet_tab']").click({force: true}) - cy.get("button.default-facets-button").click(); - - cy.get(".lhs button[data-filter-name]:nth-child(3)").click(); //remove creationDate - - cy.get("button.default-facets-button").click(); - - //cy.get("div.search-button-wrapper button").click() - - //cy.get(".facet-wrapper .button-list button").should("have.length", 4); - - //cy.get("opencb-facet-results opencga-facet-result-view").should("have.length", 4); - - }) -}) diff --git a/cypress/integration/opencga-sample-browser.spec.js b/cypress/integration/opencga-sample-browser.spec.js deleted file mode 100644 index 90455f4c2..000000000 --- a/cypress/integration/opencga-sample-browser.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import {login} from "../plugins/utils.js"; - -context("File Browser", () => { - before(() => { - login(); - }) - - it("query", () => { - cy.get("a[data-id=samples]").click({force: true}) - cy.get("div.page-title h2", {timeout: 60000}).should("be.visible").and("contain", "Sample Browser") - - cy.get("#somatic + .subsection-content label").contains( "True").click({force: true}) - - cy.get(".lhs button[data-filter-name]").should("have.length", 1); - cy.get("div.search-button-wrapper button").click(); - - cy.get(".lhs .somaticActiveFilter").click(); - cy.get(".lhs button[data-filter-name]").should("have.length", 0); - - }) - - it("aggregated query", () => { - cy.get("a[data-id=samples]").click({force: true}) - - cy.get("a[href='#facet_tab']").click({force: true}) - cy.get("button.default-facets-button").click() - cy.get("div.search-button-wrapper button").click() - - cy.get(".facet-wrapper .button-list button").should("have.length", 4); - - cy.get("opencb-facet-results opencga-facet-result-view").should("have.length", 4); - - }) -}) diff --git a/cypress/integration/opencga-variant-browser.spec.js b/cypress/integration/opencga-variant-browser.spec.js deleted file mode 100644 index d31387b11..000000000 --- a/cypress/integration/opencga-variant-browser.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import {login} from "../plugins/utils.js"; - -context("Variant Browser", () => { - before(() => { - login(); - }) - - it("query", () => { - cy.get("a[data-id=browser]").click({force: true}) - cy.get("div.page-title h2", {timeout: 60000}).should("be.visible").and("contain", "Variant Browser") - - - cy.get("input#lof").click({force: true}); - cy.get("opencga-active-filters").contains("Consequence Types 10") - cy.get("button.ctActiveFilter").click() - }) - - it("aggregated query", () => { - cy.get("a[data-id=browser]").click({force: true}) - cy.get("a[href='#facet_tab']").click({force: true}) - cy.get("button.default-facets-button").click() - cy.get("div.search-button-wrapper button").click() - - cy.wait(2000); - - cy.get("#bs-select-1-4").click({force: true}) // gene aggregation field - cy.get("#type_Select a").contains( "INSERTION").click({force: true}) - cy.get("div.search-button-wrapper button").click() - - }) -}) diff --git a/cypress/integration/playground/scripts.js b/cypress/integration/playground/scripts.js deleted file mode 100644 index 696bb2865..000000000 --- a/cypress/integration/playground/scripts.js +++ /dev/null @@ -1,111 +0,0 @@ -//import "cypress-wait-until"; - -function preventFormSubmitDefault(selector) { - cy.get(selector).then(form$ => { - form$.on("submit", e => { - e.preventDefault(); - }); - }); -} - -let i = 0 - -context("Variant Browser", () => { - beforeEach(() => { - //cy.visit("http://localhost:3000/src/#login") - }) - - it("login", () => { - - /* - cy.server( { - onRequest: () => { - i++; - }, - onResponse: () => { - i--; - } - });*/ - - /*cy.on('url:changed', url => { - //cy.visit(url); - console.log("URL CHANGED", url) - });*/ - - const username = Cypress.env("username") - - const password = Cypress.env("password") - - console.log("username", username) - console.log("password", password) - - expect(username, "username was set").to.be.a("string").and.not.be.empty - expect(password, "password was set").to.be.a("string").and.not.be.empty - - - cy.visit("http://localhost:3000/src/#login") - cy.get("#opencgaUser").type(username).should("have.value", "///") - cy.get("#opencgaPassword").type(password).should("have.value", "///") - - //cy.clock() - - cy.get("form#formLogin").submit() - - cy.wait(1000); - - //cy.visit("http://localhost:3000/src/#home"); - - cy.get("#home-nav").click() - - - //cy.reload(); - cy.url().should("include", "#home") - - //cy.window().then(win => win["alert"]("HELLO!!")) - - cy.get(".subtitle").contains( "Interactive Variant Analysis") - //cy.get(".version").contains( "v2.0.0-beta") - - cy.get("a[data-id=browser]").click({force:true}) - - //cy.wait(5000); - //cy.visit("http://localhost:3000/src/#browser"); - //cy.reload(); - //cy.url().should("include", "#browser"); - - //cy.get(".page-title").contains( "Variant Browser") - - /*cy.waitUntil(() => i > 0) - cy.waitUntil(() => i === 0)*/ - - - //cy.wait(["@POST", "@GET"]) - - //cy.tick(10000) - - //cy.get("@POST.all").should("have.length", 1) - //cy.get("@GET.all").should("have.length", 1) - - //cy.reload(); - - - - //preventFormSubmitDefault("form"); - //cy.get("button[type=submit]").click() - //cy.visit("http://localhost:3000/src/#browser") - - - //cy.visit("http://localhost:3000/src/#browser")//.should("eq", "#home") - //cy.get(".subtitle").should("have.value", "Interactive Variant Analysis") - //cy.get("a[data-id=browser]").click({force: true}) - //cy.url().should("include", "#home") - - /* - cy.get("a[data-id=browser]").click({force: true}) - cy.waitUntil(() => i > 0) - cy.waitUntil(() => i === 0) - cy.reload();*/ - - //cy.get("button[type=submit]").click() - }) -}) diff --git a/cypress/integration/playground/test-routing.js b/cypress/integration/playground/test-routing.js deleted file mode 100644 index 5d1f7cce8..000000000 --- a/cypress/integration/playground/test-routing.js +++ /dev/null @@ -1,16 +0,0 @@ -context("Variant Browser", () => { - beforeEach(() => { - // cy.visit("http://localhost:3000/src/#login") - }) - - it("login", () => { - - /*cy.get("#loginButton").within(() => { - // ends the current chain and yields null - cy.contains("Login").click().end() - })*/ - cy.visit("http://localhost:3000/src/test-routing.html") - cy.get("#about-menu").click() - - }) -}) diff --git a/cypress/plugins/constants.js b/cypress/plugins/constants.js new file mode 100644 index 000000000..aed38e2aa --- /dev/null +++ b/cypress/plugins/constants.js @@ -0,0 +1,5 @@ +/** + * Constants + * + */ +export const TIMEOUT = 60000; diff --git a/cypress/plugins/utils.js b/cypress/plugins/utils.js index 24b0f4486..d10864d32 100644 --- a/cypress/plugins/utils.js +++ b/cypress/plugins/utils.js @@ -1,8 +1,230 @@ + +/** + * https://github.com/cypress-io/cypress/issues/5743#issuecomment-650421731 + * getAttached(selector) + * getAttached(selectorFn) + * + * Waits until the selector finds an attached element, then yields it (wrapped). + * selectorFn, if provided, is passed $(document). Don't use cy methods inside selectorFn. + */ + +import {TIMEOUT} from "./constants.js"; + +Cypress.Commands.add("getAttached", selector => { + const getElement = typeof selector === "function" ? selector : $d => $d.find(selector); + let $el = null; + return cy.document().should($d => { + $el = getElement(Cypress.$($d)); + expect(Cypress.dom.isDetached($el)).to.be.false; + }).then(() => cy.wrap($el)); +}); + +export const waitTable = gridSelector => { + cy.wait(1000); // it is necessary to avoid the following negative assertion is early satisfied + cy.get(gridSelector + " div.fixed-table-loading", {timeout: 60000}).should("be.not.visible"); +}; + export const login = () => { - cy.visit("http://localhost:3000/src/#login") + cy.visit("http://localhost:3000/src/#login"); const username = Cypress.env("username"); const password = Cypress.env("password"); - cy.get("#opencgaUser").type(username) - cy.get("#opencgaPassword").type(password, {log: false}) - cy.get("form#formLogin").submit() -} + cy.get("#opencgaUser").type(username); + cy.get("#opencgaPassword").type(password, {log: false}); + cy.get("form#formLogin").submit(); + + // temp fix + cy.get(".login-overlay", {timeout: 60000}).should("be.visible"); + cy.get(".login-overlay", {timeout: 60000}).should("not.exist"); + + // switch to defined Study + if (Cypress.env("study")) { + cy.get(`a[data-fqn="${Cypress.env("study")}"]`, {timeout: 60000}).click({force: true}); + } + + +}; + +export const randomString = length => { + let result = ""; + const _length = length || 6; + const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + for (let i = 0; i < _length; i++) { + result += characters.charAt(Math.floor(Math.random() * characters.length)); + } + return result; +}; + +export const waitTableResults = gridSelector => { + cy.get(gridSelector + " div.fixed-table-loading", {timeout: 60000}).should("be.visible"); + cy.get(gridSelector + " div.fixed-table-loading", {timeout: 60000}).should("be.not.visible"); +}; + +/** + * it check the table actually contains a single result + */ +export const checkExactResult = (gridSelector, numResults = 1) => { + waitTable(gridSelector); + cy.get(gridSelector + " table", {timeout: 60000}).find("tr[data-index]", {timeout: 60000}).should("have.lengthOf", numResults); // .should("be.gte", 1); +}; + +/** + * it check the table actually contains results + */ +export const checkResults = gridSelector => { + waitTable(gridSelector); + cy.get(gridSelector + " table", {timeout: 60000}).find("tr[data-index]", {timeout: 60000}).should("have.length.gt", 0); // .should("be.gte", 1); +}; + +/** + * it check the table contains results or the message "No matching records found" + */ +export const checkResultsOrNot = (gridSelector, id) => { + waitTable(gridSelector); + cy.get(gridSelector + " .fixed-table-body > table > tbody", {timeout: 60000}).find(" > tr", {timeout: 10000}) + .should("satisfy", $els => { + + // TODO Debug this. the first print is defined the second is not + /* console.error("$els", $els) + cy.wait(1000) + console.error("$els", $els)*/ + + const $firstRow = Cypress.$($els[0]); + if ($firstRow) { + // it covers either the case of some results or 0 results + return $firstRow.data("index") === 0 || $els.text().includes("No matching records found"); + } + + }); +}; + +/** + * Given column and row coordinates, it returns the value of a single cell out of a bootstrap table + * @param {String} gridSelector CSS selector of the table + * @param {Number} colIndex column index + * @param {Number} rowIndex row index + * @param {String} invokeFn text|html + * @return {Cypress.Chainable} + */ +export const getResult = (gridSelector, colIndex = 0, rowIndex = 0, invokeFn= "text") => { + // cy.get(gridSelector + " table", {timeout: 60000}).find("tr[data-index]", {timeout: 60000}).should("have.length.gte", rowIndex); + // cy.get(gridSelector + " table", {timeout: 60000}).find(`tr[data-index=${rowIndex}] > :nth-child(${colIndex})`, {timeout: 60000}).invoke("text").as("text") + return cy.get(gridSelector + " table", {timeout: 60000}).find(`tr[data-index=${rowIndex}] > :nth-child(${colIndex + 1})`, {timeout: 60000}).first().invoke(invokeFn); +}; + +/** + * it checks whether the grid has results. + */ +export const hasResults = gridSelector => { + return cy.get(gridSelector + " .fixed-table-body > table > tbody > tr") + .then($rows => { + if ($rows.length) { + return !Cypress.$($rows[0]).hasClass("no-records-found"); + } + }); +}; + +/** + * change page in a BT table + */ +export const changePage = (gridSelector, page) => { + cy.get(gridSelector + " .fixed-table-container + .fixed-table-pagination ul.pagination li a.page-link").should("be.visible").contains(page).click(); +}; + +export const Facet = { + select: label => { + cy.get("facet-filter .facet-selector li a").contains(label).click({force: true}); + }, + // TODO add action: remove from select + remove: label => { + // TODO check whether it is active and then remove from select + // cy.get("div.facet-wrapper button[data-filter-name='" + field + "']") + cy.get("facet-filter .facet-selector li a").contains(label).click({force: true}); + }, + selectDefaultFacet: () => { + cy.get("button.default-facets-button").click(); + }, + removeActive: field => { + cy.get("div.facet-wrapper button[data-filter-name='" + field + "']").click(); + }, + checkActiveFacet: (field, value) => { + cy.get("div.facet-wrapper button[data-filter-name='" + field + "']").contains(value); + }, + checkActiveFacetLength: len => { + cy.get("div.facet-wrapper button[data-filter-value]", {timeout: TIMEOUT}).should("have.length", len); + }, + checkResultLength: len => { + cy.get("opencb-facet-results opencga-facet-result-view", {timeout: 180000}).should("have.length", len); + } +}; + +/** + * Date-filter test + */ +export const dateFilterCheck = gridSelector => { + cy.get("date-filter input[data-tab=range] + label").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=year] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=year] a").contains("2020").click(); + + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=month] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=month] a").contains("Feb").click(); + + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=day] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=start][data-field=day] a").contains("2").click(); + + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=year] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=year] a").contains("2020").click(); + + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=month] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=month] a").contains("Mar").click(); + + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=day] button").click(); + cy.get("div[data-cy='date-range'] select-field-filter[data-type=range][data-endpoint=end][data-field=day] a").contains("3").click(); + + cy.get("opencga-active-filters button[data-filter-name='creationDate']").contains("20200202-20200303"); + cy.get("opencga-active-filters button[data-filter-name='creationDate']").click(); + checkResults(gridSelector); +}; + + +/** + * Lookup for the first simple text variable + * type a random string and then check whether the button in opencga-active-filters is built correctly + */ +export const annotationFilterCheck = gridSelector => { + cy.get("opencga-annotation-filter-modal", {timeout: 60000}) + .then($wc => { + // check whether there are variableSet + if (Cypress.$("button", $wc).length) { + cy.get("div[data-cy='annotations'] button").contains("Annotation").click(); + const $tabs = Cypress.$("div.tab-pane", $wc); + // checkes whether there are VariableSets tabs + assert.isAbove($tabs.length, 0, "The number of VariableSets"); + if ($tabs.length) { + const $firstTab = Cypress.$($tabs[0]); + if ($firstTab) { + // check whether there is actually an input field in the first VariableSet, if not bypass the test + const $inputFields = Cypress.$("input[data-variable-id]", $firstTab); + if ($inputFields.length) { + cy.get("opencga-annotation-filter-modal").find("input[data-variable-id]").first().should("be.visible").then($input => { + const str = randomString(); + const variableSetId = $input.data("variableSetId"); + const variableId = $input.data("variableId"); + cy.wrap($input).type(str); + cy.get("opencga-annotation-filter-modal .modal-footer button").contains("OK").click(); + cy.get("opencga-active-filters button[data-filter-name='annotation']").contains(`annotation: ${variableSetId}:${variableId}=${str}`); + cy.get("opencga-active-filters button[data-filter-name='annotation']").click(); + checkResults(gridSelector); + }); + } else { + // return true; // cy..then($wc => {}) fails because you cannot mixing up async and sync code. + // so we can just make the test pass by check the non existence of inputs fields + cy.get("opencga-annotation-filter-modal input[data-variable-id]", {timeout: TIMEOUT}).should("not.exist"); + cy.get("opencga-annotation-filter-modal .modal-footer button").contains("OK").click(); + } + } + } + } else { + cy.wrap($wc).contains("No variableSets defined in the study"); + } + }); +}; diff --git a/dependency-graph.sh b/dependency-graph.sh new file mode 100755 index 000000000..4b1031e74 --- /dev/null +++ b/dependency-graph.sh @@ -0,0 +1,23 @@ +exclude=\ +"/node_modules|"\ +"/web_modules|"\ +"lib/jsorolla/node_modules|"\ +"lib/jsorolla/src/genome-browser|"\ +"lib/jsorolla/src/core/webcomponents/loading-spinner.js|"\ +"lib/jsorolla/src/core/NotificationUtils.js|"\ +"lib/jsorolla/src/core/utils.js|"\ +"lib/jsorolla/src/core/utilsNew.js|"\ +"lib/jsorolla/src/core/webcomponents/PolymerUtils.js|"\ +"lib/jsorolla/src/core/clients|"\ +"lib/jsorolla/src/core/visualisation|"\ +"lib/jsorolla/src/core/webcomponents/opencga/clinical/obsolete|"\ +"lib/jsorolla/src/core/webcomponents/commons/filters/deprecated|"\ +"lib/jsorolla/src/core/webcomponents/variant/deprecated|"\ +"./deprecated|"\ +"lib/jsorolla/src/core/webcomponents/Notification.js" + +depcruise "lib/jsorolla/src/core/webcomponents/**/*.js" -x "^($exclude)" --output-type dot | dot -T svg > dependency.svg +depcruise "lib/jsorolla/src/core/webcomponents/**/*.js" -x "^($exclude)" --output-type json > dependency.json + +# depcruise "lib/jsorolla/src/core/webcomponents/**/*.js" -x "^($exclude)" --output-type dot | dot -Gsplines=ortho -Grankdir=TD -T svg > dependency.svg +# depcruise "lib/jsorolla/src/core/webcomponents/**/*.js" -x "^($exclude)" --output-type ddot | dot -Gsplines=ortho -T svg > dependency.svg diff --git a/docker/iva-app/Dockerfile b/docker/iva-app/Dockerfile index e084441fa..51acccd7a 100644 --- a/docker/iva-app/Dockerfile +++ b/docker/iva-app/Dockerfile @@ -1,7 +1,7 @@ FROM httpd:2.4-alpine ## To run the docker use: -## docker build -f ./docker/Dockerfile -t iva-httpd . +## docker build -f ./docker/iva-app/Dockerfile -t iva-httpd . ## docker run -dit --name iva -p 81:80 -v [ABS_PATH]/iva/build/conf/:/usr/local/apache2/htdocs/iva/conf opencb/iva-app ## Then open: http://localhost:81/iva @@ -22,4 +22,4 @@ COPY ./build/ /usr/local/apache2/htdocs/iva/ EXPOSE 80 -CMD ["httpd-foreground"] +ENTRYPOINT ["entrypoint.sh", "httpd-foreground"] diff --git a/docker/iva-app/entrypoint.sh b/docker/iva-app/entrypoint.sh index 2228d582c..7e4836880 100755 --- a/docker/iva-app/entrypoint.sh +++ b/docker/iva-app/entrypoint.sh @@ -1,6 +1,26 @@ #!/bin/bash -echo "total args:" $# -echo "first:" $1 -echo "second:" $2 +#echo "total args:" $# +#echo "first:" $1 +#echo "second:" $2 #sed -i 's/host:".*"/host: "val" /g' /usr/local/apache2/htdocs/iva/conf/conf.js + +# launch command (httpd-foreground) +cmd=$1 +shift + +for i in "${@}"; do + case $i in + --host=*) + echo host ${i##--host=} + echo "opencga.host = ${i##--host=};" >> /usr/local/apache2/htdocs/iva/conf/config.js + shift 2 + ;; + -*|--*) + echo "Fatal error. Unknown option $i. " + exit + ;; + esac +done + +exec "$cmd" diff --git a/docs/.gitbook/assets/image (5) (1).png b/docs/.gitbook/assets/image (5) (1).png new file mode 100644 index 000000000..c178264e7 Binary files /dev/null and b/docs/.gitbook/assets/image (5) (1).png differ diff --git a/docs/.gitbook/assets/image (5) (2).png b/docs/.gitbook/assets/image (5) (2).png new file mode 100644 index 000000000..c178264e7 Binary files /dev/null and b/docs/.gitbook/assets/image (5) (2).png differ diff --git a/docs/.gitbook/assets/image (9) (1).png b/docs/.gitbook/assets/image (9) (1).png new file mode 100644 index 000000000..163d66117 Binary files /dev/null and b/docs/.gitbook/assets/image (9) (1).png differ diff --git a/docs/.gitbook/assets/image (9) (2).png b/docs/.gitbook/assets/image (9) (2).png new file mode 100644 index 000000000..163d66117 Binary files /dev/null and b/docs/.gitbook/assets/image (9) (2).png differ diff --git a/docs/.gitbook/assets/image (9) (3).png b/docs/.gitbook/assets/image (9) (3).png new file mode 100644 index 000000000..163d66117 Binary files /dev/null and b/docs/.gitbook/assets/image (9) (3).png differ diff --git a/docs/.github/README.md b/docs/.github/README.md new file mode 100644 index 000000000..c41e0e049 --- /dev/null +++ b/docs/.github/README.md @@ -0,0 +1,2 @@ +# .github + diff --git a/docs/.github/issue_template/README.md b/docs/.github/issue_template/README.md new file mode 100644 index 000000000..266a81c3d --- /dev/null +++ b/docs/.github/issue_template/README.md @@ -0,0 +1,2 @@ +# ISSUE\_TEMPLATE + diff --git a/docs/.github/issue_template/bug_report.md b/docs/.github/issue_template/bug_report.md new file mode 100644 index 000000000..8ad0b127e --- /dev/null +++ b/docs/.github/issue_template/bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' +--- + +# bug\_report + +**Describe the bug** A clear and concise description of what the bug is. + +**To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error + +**Expected behavior** A clear and concise description of what you expected to happen. + +**Screenshots** If applicable, add screenshots to help explain your problem. + +**Desktop \(please complete the following information\):** + +* OS: \[e.g. iOS\] +* Browser \[e.g. chrome, safari\] + +**Additional context** Add any other context about the problem here. + diff --git a/docs/.github/issue_template/feature_request.md b/docs/.github/issue_template/feature_request.md new file mode 100644 index 000000000..a141e81bb --- /dev/null +++ b/docs/.github/issue_template/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' +--- + +# feature\_request + +**Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when \[...\] + +**Describe the solution you'd like** A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** Add any other context or screenshots about the feature request here. + diff --git a/docs/README.md b/docs/README.md index 1e05c875e..edbe3cc13 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,16 @@ +<<<<<<< HEAD:docs/README.md # README ## Overview IVA is a generic Interactive Variant Analysis browser that can be used for the visualization of biological information from various data sources. IVA uses data from [OpenCGA](https://github.com/opencb/opencga) which is an OpenCB project. +======= +Logo + +# Overview + +The Interactive Variant Analyser (IVA) is the web user interface for OpenCGA that provides unprecedented features for real-time interaction with genomic data. It is suitable for any scale; from the detailed interpretation of a single genomic test through to assessing the genetic diversity of hundreds of thousands of aggregated genomes. It is not just for bioinformaticians; it provides simple and convenient access for biomedical researchers and clinical scientists as well. +>>>>>>> develop:README.md ### Documentation @@ -25,6 +33,13 @@ IVA is versioned following the rules from [Semantic versioning](http://semver.or ### Maintainers We recommend to contact IVA developers by writing to OpenCB mailing list opencb@googlegroups.com. The main developers and maintainers are: +<<<<<<< HEAD:docs/README.md +======= +* Ignacio Medina (im411@cam.ac.uk) (_Founder and Project Leader_) +* Antonio Altamura (antonio.altamura@genomicsengland.co.uk) +* Javier Perez Florido (javier.perez.florido.ext@juntadeandalucia.es) +* Alexis Martínez (alexis.martinez@juntadeandalucia.es) +>>>>>>> develop:README.md * Ignacio Medina \(im411@cam.ac.uk\) \(_Founder and Project Leader_\) * Javier Perez Florido \(javier.perez.florido.ext@juntadeandalucia.es\) @@ -39,22 +54,18 @@ We recommend to contact IVA developers by writing to OpenCB mailing list opencb@ IVA is an open-source and collaborative project, currently developement is mainly carried out by Stefan Gräf and Ignacio Medina teams from the University of Cambridge and Joaquin Dopazo team from CIBERER. We appreciate any help and feedback from users, you can contribute in many different ways such as simple bug reporting and feature request. Dependending on your skills you are more than welcome to develop client tools, new features or even fixing bugs. -## How to build +# How to build +IVA is mainly developed in JavaScript. It requires of OpenCB JSorolla project to be built, this is a JavaScript library developed for several OpenCB web-based projects, it can be found as Git submodule in IVA. -IVA is developed in HTML5, therefore it is mainly developed in JavaScript and makes a heavy usage of HTML and CSS. It uses Grunt as building tool. IVA also requires of OpenCB JSorolla project to be built, this is a JavaScript library developed for several OpenCB web-based projects, this can be found as Git submodule in IVA. - -Stable releases are merged and tagged at _master_ branch, you are encourage to use latest stable release for production. Current active development is carried out at _develop_ branch, only building is guaranteed and bugs are expected, use this branch for development or for testing new functionalities. The only dependency of IVA from OpenCB is JSorolla. +Stable releases are merged and tagged at _master_ branch, you are encourage to use latest stable release for production. Current active development is carried out at _develop_ branch, only building is guaranteed and bugs are expected, use this branch for development or for testing new functionalities. ### Prerequisites - -The following technologies are needed to build IVA: [Node.js](https://nodejs.org/en/), [npm](https://www.npmjs.com/) and [Grunt](http://gruntjs.com/getting-started). +To run and build IVA you need: [Node.js](https://nodejs.org/en/) and [npm](https://www.npmjs.com/). #### Installing Node.js and npm To install [Node.js](https://nodejs.org/en/) you can visit [this link](http://blog.teamtreehouse.com/install-node-js-npm-linux). -[npm](https://www.npmjs.com/) stands for _node packaged modules_ and it is the dependency manager of [Node.js](https://nodejs.org/en/). - ### Cloning IVA is an open-source project and can be downloaded either as package\(tar.gz\) from GitHub releases or source code by cloning the repository. @@ -64,11 +75,12 @@ Default _**develop**_ branch can be downloaded by executing: ```text $ git clone https://github.com/opencb/iva.git Cloning into 'iva'... -remote: Counting objects: 624, done. -remote: Total 624 (delta 0), reused 0 (delta 0), pack-reused 624 -Receiving objects: 100% (624/624), 139.37 KiB | 0 bytes/s, done. -Resolving deltas: 100% (356/356), done. -Checking connectivity... done. +remote: Enumerating objects: 126, done. +remote: Counting objects: 100% (126/126), done. +remote: Compressing objects: 100% (72/72), done. +remote: Total 10370 (delta 70), reused 85 (delta 38), pack-reused 10244 +Receiving objects: 100% (10370/10370), 4.70 MiB | 61.00 KiB/s, done. +Resolving deltas: 100% (6064/6064), done. ``` Latest stable release at _**master**_ branch can be downloaded by executing: @@ -83,41 +95,49 @@ Resolving deltas: 100% (356/356), done. Checking connectivity... done. ``` -After this, in both cases, you **must** execute the following command to fetch the JSorolla submodule \(only the first time\): +After this, in both cases, you **must** execute the following command to fetch the JSorolla submodule (only the first time): -```text +``` git submodule update --init ``` -Go to lib/jsorolla and checkout to _**develop**_ branch of Jsorolla by +Go to `./lib/jsorolla` and checkout to ***develop*** branch of Jsorolla by ```text cd lib/jsorolla git checkout develop +npm run install ``` -### Build +### Run +To run IVA in dev mode (hot reload for CSS files and hot restart (aka live reloading) for JS scripts), run -First, you must update JSorolla dependencies, from the root folder execute: +` +npm run serve +`. -```text -cd lib/jsorolla -npm install -``` +### Build +To buil IVA, just run -Finally, to build IVA execute: +` +npm run build +`. -We have to install npm packages for IVA, from the the root folder execute: +### Test +We use [Cypress.io](https://www.cypress.io/) as testing framework. -```text -npm install -``` -And now execute: +Having the project running through the command `npm run serve`, you can run the interactive E2E test suite by running the command +``` +npm run e2e +``` -```text -npm run build +#### Run tests and generate a report +To run test in headless version (no browser) and generate a report, run +``` +npm run e2e-report ``` +for more help, try ```npm run e2e-report -h```. when completed, all compiled files will be located under the _build_ folder. @@ -136,3 +156,11 @@ Prerequisite: make sure you have JDK installed, with at least version 8. If you 5. Move selenium bin and chrome bin inside that bin folder. 6. npm run test-e2e \( or ./node\_modules/.bin/nightwatch test/e2e/clinical-prioritization.js if you want execute just one\) +For Windows environment, just add the suffix `-win` +``` +npm run e2e-win +npm run e2e-report-win +``` +for more help, try ```npm run e2e-report-win -h```. + +The HTML report will be generated in `./report`. The filename will have the structure `__