Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI-Testing #1417

Merged
merged 48 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4e9b511
fixed cypress testing: to perform ui-testing run docker compose --pro…
aravindb24 Nov 7, 2024
a3002da
Merge branch 'development' of https://github.com/OpenEnergyDashboard/…
aravindb24 Nov 7, 2024
9bb5175
small change to docker-compose to autostart cypress when host is ready
aravindb24 Nov 7, 2024
937c255
restored comments
aravindb24 Nov 11, 2024
5c0d8bb
added language test
shankarp05 Nov 16, 2024
ec51256
Merge branch 'development' of https://github.com/OpenEnergyDashboard/…
aravindb24 Nov 19, 2024
b3bab27
ss
aravindb24 Nov 19, 2024
9a65cec
attach shell to test now, and run cypress commands in shell, git will…
aravindb24 Nov 19, 2024
7cbf6ce
Merge pull request #1 from aravindb24/Aravind
aravindb24 Nov 19, 2024
779ca06
moved cypress into src and updated cypress config
williamw04 Nov 22, 2024
4593d84
Initial Test for buttons
aravindb24 Nov 22, 2024
0316809
Intiial form tests
aravindb24 Nov 22, 2024
aaec689
Intial dropdown test
aravindb24 Nov 22, 2024
961749b
Intial test for links
aravindb24 Nov 22, 2024
f292d17
Initial tests for modals
aravindb24 Nov 22, 2024
3d54c4e
Initial tests for table data
aravindb24 Nov 22, 2024
05ada05
Intial test for checkboxes
aravindb24 Nov 22, 2024
3fa4dad
Intial interactive test (radio added)
aravindb24 Nov 22, 2024
a5bcbbc
Initial test for dynamic elements
aravindb24 Nov 22, 2024
3075c32
delete duplicate test and unexpose postgres serv
aravindb24 Nov 22, 2024
5c0fb28
creating test for line menu option: including line option selected, c…
williamw04 Nov 23, 2024
d2f8738
beginning test for hide options button
shankarp05 Dec 1, 2024
85ba9f5
adding to hide options button test
shankarp05 Dec 6, 2024
9155b34
finishing hide options test
shankarp05 Dec 6, 2024
c81bb9a
starting tests for testing pages dropdown
shankarp05 Dec 10, 2024
8f7b666
adding to groups test
shankarp05 Dec 10, 2024
bedf3b3
finishing group button testing
shankarp05 Dec 10, 2024
ee99424
starting meters button testing
shankarp05 Dec 10, 2024
e3ab402
finishing meters test
shankarp05 Dec 10, 2024
0880bc1
beginning tooltip icon testing
shankarp05 Dec 11, 2024
a70d627
adding to tooltip icon test
shankarp05 Dec 11, 2024
c628d53
finishing tooltip test
shankarp05 Dec 11, 2024
aef734f
Merge pull request #2 from aravindb24/shankar
shankarp05 Dec 18, 2024
a40b54c
Merge branch 'Aravind' into development
williamw04 Dec 27, 2024
30ccb35
Merge branch 'williamw04_ui' into development
williamw04 Dec 27, 2024
81f33c4
relocated testing file location
williamw04 Dec 27, 2024
9f194fb
line ui testing expanded and notes regarding future testing
williamw04 Dec 29, 2024
4f58471
Merge branch 'development' into development
williamw04 Dec 30, 2024
de05934
pushing changes to fix check
williamw04 Dec 30, 2024
ccace74
fix to health issue and addressed other comments
williamw04 Jan 12, 2025
cdba3e3
formatting
huss Jan 12, 2025
ad2d1f6
location of screenshots
huss Jan 12, 2025
ed46549
TODO for default line graphic
huss Jan 12, 2025
b587678
adjusted the screenshots path in cypress config, removed eextra line …
williamw04 Jan 16, 2025
bed7713
resolved merge conflicts
williamw04 Jan 16, 2025
5468e1d
updated git ignore to ignore screenshots within the cypress screensho…
williamw04 Jan 16, 2025
d46051b
commented out general_ui test needs to be fixed in the future
williamw04 Jan 19, 2025
e345a24
some changes
huss Jan 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ nohup.out
.vscode/settings.json

# tmp file
src/server/tmp/*
src/server/tmp/*

#ui-testing screenshots
src/cypress/screenshots/*
16 changes: 16 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { defineConfig } from 'cypress';

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
specPattern: 'src/cypress/e2e/*.cy.ts',
supportFile: 'src/cypress/support/e2e.ts',
screenshotsFolder: 'src/cypress/screenshots/e2e'
}
});
38 changes: 34 additions & 4 deletions docker-compose.yml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ services:
- POSTGRES_PASSWORD=pleaseChange # default postgres password that should be changed for security.
volumes:
- ./postgres-data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 10s
retries: 3
# ports:
# - "5432:5432"
# Uncomment the above lines to enable access to the PostgreSQL server
Expand Down Expand Up @@ -68,10 +73,15 @@ services:
# and comment out the debug port and 3000:3000 line above
# Don't bring this up without the DB
depends_on:
- database
# database:
# - database
database:
# We need the database and it has to be ready for work (see healthcheck above).
# condition: service_healthy
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
timeout: 5s
retries: 5
# Lets docker compose up work right
# If environment variable install_args is not set then it becomes blank without warning user.
command:
Expand All @@ -81,4 +91,24 @@ services:
"${install_args:-}"
]
# Use this if you are using a docker-compose that is earlier than version 2 and comment out the one above.
# command: ["bash", "./src/scripts/installOED.sh"]
# command: ["bash", "./src/scripts/installOED.sh"]

# Cypress testing service
cypress:
image: cypress/included
profiles:
- ui-testing
environment:
- CYPRESS_BASE_URL=http://web:3000
- DISPLAY=:99
working_dir: /usr/src/app
depends_on:
web:
condition: service_healthy
volumes:
- ./:/usr/src/app
entrypoint: >
/bin/sh -c "
rm -f /tmp/.X99-lock &&
Xvfb :99 -screen 0 1024x768x16"

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 98 additions & 0 deletions src/cypress/e2e/general_ui.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// TODO: The commented out tests were attempts to test the UI that are
// not yet working. They need to be fixed.

describe('UI Functionality Tests for Open Energy Dashboard', () => {
beforeEach(() => {
// Visit the page before each test
cy.visit('/');
});

// it('Tests all buttons functionality', () => {
// // Ensure buttons are visible and clickable
// cy.get('button').should('have.length.greaterThan', 0); // Ensure buttons exist
// cy.get('button').each((button) => {
// cy.wrap(button).should('be.visible'); // Check visibility
// cy.wrap(button).click({ force: true }); // Test click
// });
// });

// it('Tests all form inputs', () => {
// // Test text and email inputs
// cy.get('input[type="text"], input[type="email"]').each((input) => {
// cy.wrap(input).should('be.visible').type("Sample Text"); // Check visibility and type
// });

// // Test password inputs
// cy.get('input[type="password"]').each((input) => {
// cy.wrap(input).should('be.visible').type('password');
// });

// // Test textareas
// cy.get('textarea').each((textarea) => {
// cy.wrap(textarea).should('be.visible').type('Sample description text');
// });

// // Submit forms
// cy.get('form').each((form) => {
// cy.wrap(form).within(() => {
// cy.get('button[type="submit"], input[type="submit"]').click({ force: true });
// });
// });
// });

// it('Tests dropdown menus', () => {
// // Ensure dropdowns are visible and options are selectable
// cy.get('select').should('have.length.greaterThan', 0); // Ensure dropdowns exist
// cy.get('select').each((dropdown) => {
// cy.wrap(dropdown)
// .should('be.visible') // Check visibility
// .find('option')
// .should('have.length.greaterThan', 1); // Ensure options exist

// // Select the first option (change index as needed)
// cy.wrap(dropdown).select(0);
// });
// });

it('Tests links for navigation', () => {
// Ensure links have valid href attributes
cy.get('a[href]').each((link) => {
cy.wrap(link).should('have.attr', 'href').and('not.be.empty'); // Check href exists
});
});

// it('Tests modals for correct behavior', () => {
// // Ensure modals can be triggered and closed
// cy.get('[data-bs-toggle="modal"]').each((modalTrigger) => {
// cy.wrap(modalTrigger).should('be.visible').click(); // Trigger modal
// cy.get('.modal').should('be.visible'); // Check modal is visible
// cy.get('.modal .close').click(); // Close modal
// cy.get('.modal').should('not.be.visible'); // Check modal is closed
// });
// });
// it('Tests tables for data population', () => {
// // Ensure tables are populated with rows
// cy.get('table').should('have.length.greaterThan', 0); // Ensure tables exist
// cy.get('table').each((table) => {
// cy.wrap(table).find('tr').should('have.length.greaterThan', 1); // At least one row
// });
// });
// it('Tests interactive inputs (checkboxes and radio)', () => {
// // Check and uncheck checkboxes
// cy.get('input[type="checkbox"]').each((checkbox) => {
// cy.wrap(checkbox).check({ force: true }).should('be.checked'); // Check it
// cy.wrap(checkbox).uncheck({ force: true }).should('not.be.checked'); // Uncheck it
// });
// cy.get('input[type="radio"]').each((radio) => {
// cy.wrap(radio).check({ force: true }).should('be.checked'); // Check radio
// });
// });
// it('Tests for dynamic elements', () => {
// // Ensure dynamically loaded elements exist and are visible
// cy.get('[data-dynamic]').should('exist').and('be.visible');
// });
});
38 changes: 38 additions & 0 deletions src/cypress/e2e/hideOptions.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

describe("Options Menu Tests", () => {
beforeEach(() => {
// Visit the OED application
cy.visit("/");
});

it("should toggle the visibility of graph configuration options when 'Hide options' is clicked", () => {
// Open the Options dropdown
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").click();

// Click "Hide options"
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > button:nth-child(2)").click();

// Verify that graph configuration options are hidden
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").should("not.exist"); // pages
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").should("not.exist"); // options
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > a:nth-child(4)").should("not.exist"); // help



// Click "Menu" again to toggle visibility back
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > button").click();
cy.get("body > div:nth-child(4) > div > div.modal.fade.show > div > div > div.modal-header > div > h6 > div > nav > div > ul > li:nth-child(3) > a").click();
cy.get("body > div:nth-child(4) > div > div.modal.fade.show > div > div > div.modal-header > div > h6 > div > nav > div > ul > li.dropdown.show.nav-item > div > button:nth-child(2)").click();



cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").should("be.visible"); // pages
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").should("be.visible"); // options
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > a:nth-child(4)").should("be.visible"); // help


});
});
25 changes: 25 additions & 0 deletions src/cypress/e2e/initLangTest.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

describe("Language Selector Tests", () => {
beforeEach(() => {
// Visit the OED application
cy.visit("/");
});

it("should update the UI and React state when the language is changed", () => {
// Open the language selection dropdown

cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").click();
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > div.dropdown.dropstart > a").click();


// Select a specific language (e.g., Spanish)
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > div.dropdown.dropstart.show > div").contains("Español").click();

// Verify that UI elements are updated to the selected language
cy.get("body").should("contain", "Tipo de gráfico"); // Example text in Spanish for "Graph Type"

});
});
92 changes: 92 additions & 0 deletions src/cypress/e2e/line.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// TODO These tests assume a clean setup/test data. In the future we should wipe the database
// and load the needed data (maybe without the actual meter data until needed) in a similar way
// to how the Chai/Mocha tests work.

// This test is a great template to start with for understanding testing using cypress.
describe('testing line graph selecting groups and meters and test for plotly line graph ', () => {
beforeEach(() => {
// Visit the OED application
cy.visit('/');
});

// Graph Type is Line.
// TODO This is the default line type when OED is created but can be changed by the admin. It might be good
// to first set it to this value at some point (but it does make another possible failure).
it('should display a line graph type automatically', () => {
// Find the line chart
cy.get('#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div.dropdown > button').should('have.text', 'Line');
cy.screenshot('ShowLineTypeOption')

});
// Checking all group options
it('groups should be clickable and display 10 options and 1 incompatible option', () => {
// Find and click the group
cy.get('#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div:nth-child(4) > div:nth-child(2) > div > div.css-1fdsijx-ValueContainer').click().should('be.visible');
// Check if the 10 options are there
cy.get('#react-select-2-listbox > div:nth-child(1) > div:nth-child(2)').children().should('have.length', 10);
cy.get('#react-select-2-group-0-heading > div > span.badge.bg-primary.rounded-pill').should('have.text', '10');
// check if the incompatible option is visible and not clickable
cy.get('#react-select-2-option-1-0').should('exist')
.should('have.attr', 'aria-disabled', 'true') // Check the aria-disabled attribute
.should('have.attr', 'tabindex', '-1') // Validate tabindex to confirm it’s not focusable
});
// Checking all meter options
it('selecting menu option should display 25 options and plotly graph', () => {
// open menu option
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div:nth-child(4) > div:nth-child(4) > div > div.css-1fdsijx-ValueContainer").click().should('be.visible');
// Verify all options
cy.get("#react-select-3-listbox > div > div:nth-child(2)").children().should('have.length', 25);
// click on Cos 23 Min KWH
cy.get("#react-select-3-option-0-0").should('exist').click();

// plotly element show be dynamically created: check for plotly display
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div")
.should('exist');

//meter name should be displayed
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(3) > g.infolayer > g.legend > g > g > g > text").should('have.text', 'Cos 23 Min kWh');

// checking x-axis labels
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(1) > text").should('have.text', 'Mar 2020');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(2) > text").should('have.text', 'May 2020');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(3) > text").should('have.text', 'Jul 2020');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(4) > text").should('have.text', 'Sep 2020');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(5) > text").should('have.text', 'Nov 2020');

// checking y-axis labels
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(1) > text").should('have.text', '0');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(2) > text").should('have.text', '0.5');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(3) > text").should('have.text', '1');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(4) > text").should('have.text', '1.5');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(5) > text").should('have.text', '2');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(6) > text").should('have.text', '2.5');
cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(7) > text").should('have.text', '3');


/*
TODO: We want to check if the graph displays correct information.
After a meter or group is selected a get request is made to the server to get the data for the graph to the following endpoint:
http://localhost:3000/api/unitReadings/line/meters/21?timeInterval=all&graphicUnitId=1
The response is a json object with the data that is used to plot the graph.
It might be possible to check the json object to see if the data is correct.

Testing methods to
The line in the graph is rendered as path class ="js-line"

Main Graph:
#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.plot > g > g > g.lines > path

Drag Bar:
#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(3) > g.infolayer > g.rangeslider-container > g.rangeslider-rangeplot.xy > g.plot > g > g > g.lines > path

We could possibly simulate moving a mouse over the graph to check if the data is correct.
Clicking and dragging the bottom drag bar then refreshing the page

And checking the time interval in which the data is displayed. (From seconds to day...)
*/
});
});
25 changes: 25 additions & 0 deletions src/cypress/e2e/pagesGroups.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

describe("Navigation to Groups Page", () => {
beforeEach(() => {
// Visit the application home page
cy.visit("/");
});

it("should navigate to the Groups page when 'Groups' is clicked from the Pages dropdown", () => {
// Open the Pages dropdown
cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").click();

// Click the 'Groups' option in the dropdown
cy.contains("Groups").click();

// Verify that the Groups page has the correct title
cy.get("h2").should("have.text", "Groups");

// Verify the tooltip icon is present in the title
cy.get("h2 > div > i").should("have.attr", "data-for", "groups");
cy.get("h2 > div > i").should("have.attr", "data-tip", "help.groups.groupview");
});
});
Loading
Loading