Skip to content

Commit a874775

Browse files
CopilotChaosbit
andcommitted
Fix web component integration issues and improve Cypress commands
Co-authored-by: Chaosbit <55083+Chaosbit@users.noreply.github.com>
1 parent a35b8f7 commit a874775

4 files changed

Lines changed: 59 additions & 31 deletions

File tree

cypress/e2e/description-visibility.cy.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ describe('Description Visibility and Layout', () => {
2020

2121
it('should keep workout list descriptions within bounds', () => {
2222
// Expand first exercise in workout list
23-
cy.getExerciseItems().first().find('.exercise-header').click()
24-
cy.getExerciseItems().first().should('have.class', 'expanded')
23+
cy.getFirstExerciseItem().find('.exercise-header').click()
24+
cy.getFirstExerciseItem().should('have.class', 'expanded')
2525

2626
// Check visibility and bounds (allow margin for padding and mobile rendering)
2727
cy.get('.exercise-item.expanded .exercise-description').should('be.visible')
@@ -43,7 +43,7 @@ describe('Description Visibility and Layout', () => {
4343
cy.get('.description-content').should('have.css', 'text-align').and('match', /left|start/)
4444

4545
// Workout list descriptions should be readable
46-
cy.getExerciseItems().first().find('.exercise-header').click()
46+
cy.getFirstExerciseItem().find('.exercise-header').click()
4747
cy.get('.exercise-item.expanded .exercise-description p').should('be.visible')
4848
})
4949

@@ -60,7 +60,7 @@ describe('Description Visibility and Layout', () => {
6060
})
6161

6262
// Test workout list on mobile
63-
cy.getExerciseItems().first().find('.exercise-header').click()
63+
cy.getFirstExerciseItem().find('.exercise-header').click()
6464
cy.get('.exercise-item.expanded .exercise-description').should('be.visible')
6565
cy.get('.exercise-item.expanded .exercise-description').then($desc => {
6666
const rect = $desc[0].getBoundingClientRect()
@@ -114,7 +114,7 @@ Rest - 0:02`
114114
cy.get('.description-content p').should('have.length', 2)
115115

116116
// Test workout list with long text
117-
cy.getExerciseItems().first().find('.exercise-header').click()
117+
cy.getFirstExerciseItem().find('.exercise-header').click()
118118
cy.get('.exercise-item.expanded .exercise-description').should('be.visible')
119119
cy.get('.exercise-item.expanded .exercise-description p').should('have.length', 2)
120120

cypress/e2e/timer-functionality.cy.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Timer Functionality', () => {
1818
cy.getWorkoutControlState('pause').should('be.enabled')
1919
cy.getWorkoutControlState('skip').should('be.enabled')
2020

21-
cy.getExerciseItems().first().should('have.class', 'current')
21+
cy.getExerciseItem(0).should('have.class', 'current')
2222
})
2323

2424
it('should pause and resume the timer', () => {
@@ -59,8 +59,8 @@ describe('Timer Functionality', () => {
5959
cy.getTimerDisplay().should('contain', '0:02')
6060
cy.get('#progressText').should('contain', 'Exercise 2 of 6')
6161

62-
cy.getExerciseItems().first().should('have.class', 'completed')
63-
cy.getExerciseItems().eq(1).should('have.class', 'current')
62+
cy.getExerciseItem(0).should('have.class', 'completed')
63+
cy.getExerciseItem(1).should('have.class', 'current')
6464
})
6565

6666
it('should reset the workout', () => {
@@ -76,7 +76,7 @@ describe('Timer Functionality', () => {
7676
cy.getWorkoutControlState('pause').should('be.disabled')
7777
cy.getWorkoutControlState('skip').should('be.disabled')
7878

79-
cy.getExerciseItems().first().should('have.class', 'current')
79+
cy.getExerciseItem(0).should('have.class', 'current')
8080
})
8181

8282
it('should automatically advance through exercises', () => {
@@ -124,14 +124,14 @@ describe('Timer Functionality', () => {
124124
cy.clickWorkoutControl('start')
125125

126126
cy.clickWorkoutControl('skip')
127-
cy.getExerciseItems().first().should('have.class', 'completed')
127+
cy.getExerciseItem(0).should('have.class', 'completed')
128128

129129
cy.clickWorkoutControl('skip')
130-
cy.getExerciseItems().eq(1).should('have.class', 'completed')
130+
cy.getExerciseItem(1).should('have.class', 'completed')
131131

132132
cy.clickWorkoutControl('skip')
133-
cy.getExerciseItems().eq(2).should('have.class', 'completed')
134-
cy.getExerciseItems().eq(3).should('have.class', 'current')
133+
cy.getExerciseItem(2).should('have.class', 'completed')
134+
cy.getExerciseItem(3).should('have.class', 'current')
135135
})
136136

137137
it('should handle timer countdown accuracy', () => {

cypress/support/commands.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,38 @@ Cypress.Commands.add('clickExercise', (exerciseIndex) => {
111111
* Get exercise items from the exercise list component
112112
*/
113113
Cypress.Commands.add('getExerciseItems', () => {
114-
return cy.getShadow('exercise-list', '.exercise-item');
114+
return cy.get('exercise-list').then(($component) => {
115+
const component = $component[0];
116+
if (!component.shadowRoot) {
117+
throw new Error('ExerciseList component does not have shadow DOM');
118+
}
119+
const exerciseItems = component.shadowRoot.querySelectorAll('.exercise-item');
120+
return cy.wrap(exerciseItems);
121+
});
122+
});
123+
124+
/**
125+
* Get a specific exercise item by index
126+
*/
127+
Cypress.Commands.add('getExerciseItem', (index) => {
128+
return cy.get('exercise-list').then(($component) => {
129+
const component = $component[0];
130+
if (!component.shadowRoot) {
131+
throw new Error('ExerciseList component does not have shadow DOM');
132+
}
133+
const exerciseItems = component.shadowRoot.querySelectorAll('.exercise-item');
134+
if (index >= exerciseItems.length) {
135+
throw new Error(`Exercise index ${index} out of range. Found ${exerciseItems.length} exercises.`);
136+
}
137+
return cy.wrap(exerciseItems[index]);
138+
});
139+
});
140+
141+
/**
142+
* Get the first exercise item
143+
*/
144+
Cypress.Commands.add('getFirstExerciseItem', () => {
145+
return cy.getExerciseItem(0);
115146
});
116147

117148
/**

js/workout-app.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,18 @@ export class WorkoutApp {
376376
// Release screen wake lock when workout completes
377377
this.screenWakeManager.releaseWakeLock();
378378

379-
this.currentExercise.textContent = 'Workout Complete! 🎉';
380-
this.timerDisplay.textContent = '00:00';
381-
this.timerDisplay.style.display = 'block';
382-
this.repsDisplay.style.display = 'none';
383-
this.repCompletion.style.display = 'none';
384-
this.progressFill.style.width = '100%';
379+
// Update timer display component to show completion
380+
if (this.timerDisplayComponent) {
381+
const completionExercise = {
382+
name: 'Workout Complete! 🎉',
383+
duration: 0,
384+
exerciseType: 'timer'
385+
};
386+
this.timerDisplayComponent.setExercise(completionExercise);
387+
this.timerDisplayComponent.setAttribute('time-remaining', '0');
388+
this.timerDisplayComponent.setAttribute('is-running', 'false');
389+
}
390+
385391
this.updateControls();
386392
this.updateWorkoutList();
387393

@@ -411,11 +417,8 @@ export class WorkoutApp {
411417
* Update progress bar
412418
*/
413419
updateProgressBar() {
414-
// Legacy progress bar update (if still needed)
415-
if (this.progressFill) {
416-
const progress = this.timerManager.getProgress();
417-
this.progressFill.style.width = `${progress}%`;
418-
}
420+
// Progress bar is now handled by the timer display web component
421+
// This method is kept for backward compatibility but no longer needed
419422
}
420423

421424
/**
@@ -606,11 +609,6 @@ export class WorkoutApp {
606609
this.loadCurrentExercise();
607610
}
608611

609-
// Update legacy elements if they exist
610-
if (this.progressFill) {
611-
this.progressFill.style.width = '0%';
612-
}
613-
614612
this.updateControls();
615613
this.updateWorkoutList();
616614
this.updateWorkoutContextComponent();
@@ -635,7 +633,6 @@ export class WorkoutApp {
635633
const exercise = this.workout.exercises[this.currentExerciseIndex];
636634
if (exercise && exercise.exerciseType === 'reps' && !exercise.completed) {
637635
exercise.completed = true;
638-
this.progressFill.style.width = '100%';
639636

640637
// Give enough delay to ensure UI updates properly but allow faster test execution
641638
setTimeout(() => {

0 commit comments

Comments
 (0)