Skip to content

Commit 765115b

Browse files
authored
Implement Cypress testing for Music Blocks (#4362)
* Implemented Cypress tests and resolved package conflicts * script for running test added
1 parent 5e5dba7 commit 765115b

File tree

7 files changed

+5757
-2560
lines changed

7 files changed

+5757
-2560
lines changed

cypress.config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const { defineConfig } = require("cypress");
2+
3+
module.exports = defineConfig({
4+
e2e: {
5+
setupNodeEvents(on, config) {
6+
// implement node event listeners here
7+
},
8+
viewportWidth: 1400,
9+
viewportHeight: 1000,
10+
testIsolation: false
11+
},
12+
});

cypress/e2e/main.cy.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
Cypress.on("uncaught:exception", (err, runnable) => {
2+
return false;
3+
});
4+
5+
describe("MusicBlocks Application", () => {
6+
before(() => {
7+
cy.visit("http://localhost:3000");
8+
});
9+
10+
afterEach(() => {
11+
console.log("Next test running, no reload should happen");
12+
});
13+
14+
describe("Loading and Initial Render", () => {
15+
it("should display the loading animation and then the main content", () => {
16+
cy.get("#loading-image-container").should("be.visible");
17+
cy.contains("#loadingText", "Loading Complete!", { timeout: 20000 }).should("be.visible");
18+
cy.wait(10000);
19+
cy.get("#canvas", { timeout: 10000 }).should("be.visible");
20+
});
21+
22+
it("should display the Musicblocks guide page", () => {
23+
cy.get(".heading").contains("Welcome to Music Blocks");
24+
});
25+
});
26+
27+
describe("Audio Controls", () => {
28+
it("should have a functional play button", () => {
29+
cy.get("#play").should("be.visible").click();
30+
cy.window().then((win) => {
31+
const audioContext = win.Tone.context;
32+
cy.wrap(audioContext.state).should("eq", "running");
33+
});
34+
});
35+
36+
it("should have a functional stop button", () => {
37+
cy.get("#stop").should("be.visible").click();
38+
});
39+
});
40+
41+
describe("Toolbar and Navigation", () => {
42+
it("should open the language selection dropdown", () => {
43+
cy.get("#aux-toolbar").invoke("show");
44+
cy.get("#languageSelectIcon").click({ force: true });
45+
cy.get("#languagedropdown").should("be.visible");
46+
});
47+
48+
it("should toggle full-screen mode", () => {
49+
cy.get("#FullScreen").click();
50+
cy.document().its("fullscreenElement").should("exist");
51+
cy.get("#FullScreen").click();
52+
cy.document().its("fullscreenElement").should("not.exist");
53+
});
54+
55+
it("should toggle the toolbar menu", () => {
56+
cy.get("#toggleAuxBtn").click();
57+
cy.get("#aux-toolbar").should("be.visible");
58+
cy.get("#toggleAuxBtn").click();
59+
cy.get("#aux-toolbar").should("not.be.visible");
60+
});
61+
});
62+
63+
describe("File Operations", () => {
64+
it("should open the file load modal", () => {
65+
cy.get("#load").click();
66+
cy.get("#myOpenFile").should("exist");
67+
});
68+
69+
it("should open the save dropdown", () => {
70+
cy.get("#saveButton").click();
71+
cy.get("#saveddropdownbeg").should("be.visible");
72+
});
73+
74+
it("should display file save options", () => {
75+
cy.get("#saveButton").click();
76+
cy.get("#saveddropdownbeg").should("be.visible");
77+
cy.get("#save-html-beg").should("exist");
78+
cy.get("#save-png-beg").should("exist");
79+
});
80+
81+
it('should click the New File button and verify "New Project" appears', () => {
82+
cy.get('#newFile > .material-icons')
83+
.should('exist')
84+
.and('be.visible');
85+
cy.get('#newFile > .material-icons').click();
86+
cy.wait(500);
87+
cy.contains('New project').should('be.visible');
88+
});
89+
});
90+
91+
describe("UI Elements", () => {
92+
it('should verify that bottom bar elements exist and are visible', () => {
93+
const bottomBarElements = [
94+
'#Home\\ \\[HOME\\] > img',
95+
'#Show\\/hide\\ blocks > img',
96+
'#Expand\\/collapse\\ blocks > img',
97+
'#Decrease\\ block\\ size > img',
98+
'#Increase\\ block\\ size > img'
99+
];
100+
101+
bottomBarElements.forEach(selector => {
102+
cy.get(selector).should('exist').and('be.visible');
103+
});
104+
});
105+
106+
it('should verify sidebar elements exist, are visible, and clickable', () => {
107+
const sidebarElements = [
108+
'thead > tr > :nth-child(1) > img',
109+
'tr > :nth-child(2) > img',
110+
'tr > :nth-child(3) > img'
111+
];
112+
113+
sidebarElements.forEach(selector => {
114+
cy.get(selector)
115+
.should('exist')
116+
.and('be.visible')
117+
.click();
118+
});
119+
});
120+
121+
it('should verify that Grid, Clear, and Collapse elements exist and are visible', () => {
122+
const elements = [
123+
'#Grid > img',
124+
'#Clear',
125+
'#Collapse > img'
126+
];
127+
elements.forEach(selector => {
128+
cy.get(selector).should('exist').and('be.visible');
129+
});
130+
});
131+
132+
it('should verify that all nth-child elements from 1 to 6 exist', () => {
133+
for (let i = 1; i <= 6; i++) {
134+
cy.get(`[width="126"] > tbody > :nth-child(${i})`)
135+
.should('exist')
136+
.and('be.visible');
137+
}
138+
});
139+
});
140+
141+
describe("Planet Page Interaction", () => {
142+
it('should load the Planet page and return to the main page when clicking the close button', () => {
143+
cy.get('#planetIcon > .material-icons')
144+
.should('exist')
145+
.and('be.visible')
146+
.click();
147+
cy.get('#planet-iframe')
148+
.should('be.visible');
149+
});
150+
});
151+
152+
});

cypress/fixtures/example.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "Using fixtures to represent data",
3+
"email": "[email protected]",
4+
"body": "Fixtures are a great way to mock data for responses to routes"
5+
}

cypress/support/commands.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// ***********************************************
2+
// This example commands.js shows you how to
3+
// create various custom commands and overwrite
4+
// existing commands.
5+
//
6+
// For more comprehensive examples of custom
7+
// commands please read more here:
8+
// https://on.cypress.io/custom-commands
9+
// ***********************************************
10+
//
11+
//
12+
// -- This is a parent command --
13+
// Cypress.Commands.add('login', (email, password) => { ... })
14+
//
15+
//
16+
// -- This is a child command --
17+
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
18+
//
19+
//
20+
// -- This is a dual command --
21+
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
22+
//
23+
//
24+
// -- This will overwrite an existing command --
25+
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

cypress/support/e2e.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ***********************************************************
2+
// This example support/e2e.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
// Import commands.js using ES2015 syntax:
17+
import './commands'

0 commit comments

Comments
 (0)