Skip to content

chore: tests added for rotor, goto extrema, hover#489

Open
aarthy2000 wants to merge 7 commits into
mainfrom
chore/test
Open

chore: tests added for rotor, goto extrema, hover#489
aarthy2000 wants to merge 7 commits into
mainfrom
chore/test

Conversation

@aarthy2000

Copy link
Copy Markdown
Contributor

Pull Request

Description

Related Issues

Changes Made

Screenshots (if applicable)

Checklist

  • I have read the Contributor Guidelines.
  • I have performed a self-review of my own code and ensured it follows the project's coding standards.
  • I have tested the changes locally following ManualTestingProcess.md, and all tests related to this pull request pass.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation, if applicable.
  • I have added appropriate unit tests, if applicable.

Additional Notes

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Code Review: PR #489 - Tests for Rotor, Goto Extrema, and Hover

Thank you for this comprehensive test coverage! The implementation is well-documented and functional, but there are several critical issues that need to be addressed before merging.

🔴 Critical Issues (Must Fix Before Merge)

1. Debug Code Left in Production

Location: Multiple files contain console.log statements that should be removed:

  • e2e_tests/page-objects/plots/barplot-page.ts:478
  • e2e_tests/specs/barplot.spec.ts:402, 408, 414
// Remove these:
console.log(text);
console.log('first', firstPoint);
console.log('lower?', isLowerValueMode);
console.log('second', secondPoint);

2. Missing Semicolon (Syntax Error)

Location: e2e_tests/utils/constants.ts:220

static readonly EXTREMA_TARGET_1 = '#extrema-target-1'  // Missing semicolon

This violates the TypeScript style guide requirement.

3. Invalid Playwright Configuration

Location: e2e_tests/config/test-config.ts:54

trace: 'retry-with-trace',  // ❌ Invalid option

Valid Playwright trace options are: 'on', 'off', 'retain-on-failure', 'on-first-retry'. Please use one of these.

4. Massive Code Duplication (DRY Violation)

Most Critical Issue: Approximately 250 lines of identical code are duplicated across 9 page object files:

  • barplot-page.ts
  • boxplotHorizontal-page.ts
  • boxplotVertical-page.ts
  • dodgedBarplot-page.ts
  • heatmap-page.ts
  • histogram-page.ts
  • lineplot-page.ts
  • multiLineplot-page.ts
  • stackedBarplot-page.ts

Duplicated Methods (all identical):

  • moveToNextRotorMode()
  • moveToPrevRotorMode()
  • getCurrentRotorMode()
  • isRotorModeActive()
  • navigateToRotorMode()
  • openGoToExtremaModal()
  • closeGoToExtremaModal()
  • isGoToExtremaModalVisible()
  • goToExtremaMoveUp()
  • goToExtremaMoveDown()
  • selectExtremaTarget()
  • getExtremaTargets()
  • getSelectedExtremaTarget()
  • goToMaximum()
  • goToMinimum()

Impact: ~2,250 lines of duplicated code (9 files × 250 lines)

Recommendation: Move these methods to BasePage since they're identical across all plot types. This follows the DRY principle and the repository's existing pattern (you already did this correctly for the settings modal methods!).

5. Unused Constants

Location: e2e_tests/utils/constants.ts

static readonly EXTREMA_TARGET_0 = '#extrema-target-0';
static readonly EXTREMA_TARGET_1 = '#extrema-target-1';

These are defined but never used. The code uses template literals instead: `#extrema-target-${index}`


🟡 Medium Priority Issues (Should Fix)

1. Weak Test Assertions

Location: e2e_tests/specs/histogram.spec.ts:386-410

The histogram rotor tests use .toBeTruthy() which only checks non-empty values:

const firstPoint = await histogramPage.getCurrentDataPointInfo();
expect(firstPoint).toBeTruthy();  // ❌ Too weak

Compare to barplot tests which verify actual values:

const firstPoint = await barPlotPage.getCurrentDataPointInfo();
expect(firstPoint).toContain('Adelie');  // ✅ Verifies specific data

Recommendation: Update histogram tests to verify actual data point values.

2. Potential Infinite Loop

Location: All page objects with getExtremaTargets() method

while (true) {  // No safety limit
  const targetElement = await this.page.$(`#extrema-target-${index}`);
  if (!targetElement) break;
  // ...
  index++;
}

Recommendation: Add a max iteration safety check:

const MAX_TARGETS = 100;
while (index < MAX_TARGETS) {
  // ...
}

3. Inconsistent Timeout Values

Modal operations use different timeouts without clear reasoning:

  • Open operations: 5000ms
  • Close operations: 2000ms

Recommendation: Extract to constants and use consistent values:

static readonly MODAL_OPEN_TIMEOUT = 5000;
static readonly MODAL_CLOSE_TIMEOUT = 5000;

4. Incomplete Error Context

Location: e2e_tests/page-objects/base-page.ts:905

if (!boundingBox) {
  throw new Error('Failed to get SVG bounding box');  // Which SVG?
}

Recommendation: Include the selector in error messages:

throw new Error(`Failed to get SVG bounding box for selector: ${svgSelector}`);

5. Missing Input Validation

Location: SVG helper methods in base-page.ts

The hoverOnSvgPoint() and clickOnSvgPoint() methods don't validate that relativeX and relativeY are in the expected 0-1 range:

protected async hoverOnSvgPoint(
  svgSelector: string,
  relativeX: number,  // Should validate: 0 <= value <= 1
  relativeY: number,  // Should validate: 0 <= value <= 1
): Promise<void> {
  // ...
}

🟢 Low Priority (Nice to Have)

  1. Use data-testid attributes instead of text-based selectors for more robust tests
  2. Add type safety for hover mode values (use enum or type union instead of string)
  3. Log errors even when returning default values (e.g., in isHoverModeVisible())
  4. Verify correct data point in hover/click tests (currently only check that something was selected)
  5. Add negative test cases for error scenarios (boundary conditions, modal failures, etc.)

✅ What's Done Well

  1. Excellent JSDoc Documentation: All methods have comprehensive comments with proper @param, @returns, and @throws tags
  2. Type Safety: Proper TypeScript typing throughout with no use of any
  3. Consistent Error Handling: Well-structured try-catch blocks with proper error messages
  4. Good Use of Inheritance: Settings modal methods correctly placed in BasePage
  5. Descriptive Naming: Clear, self-documenting method names
  6. Comprehensive Test Coverage: Good coverage of happy paths and state transitions
  7. Following Conventions: Matches repository's TypeScript style guide (2-space indent, single quotes, camelCase)

📋 Summary

Overall Assessment: The PR implements valuable test functionality with good documentation, but has critical code quality issues that must be resolved.

Lines Changed: 29,498 additions, 3 deletions (most additions are HTML example files)

Approval Status: ❌ Request Changes

Required Actions:

  1. Remove all debug console.log statements
  2. Fix missing semicolon in constants.ts
  3. Fix invalid Playwright trace configuration
  4. Refactor duplicated code - move common rotor/extrema methods to BasePage (this is the biggest issue)
  5. Remove unused constants
  6. Strengthen test assertions in histogram tests
  7. Add input validation and safety checks

Once these issues are addressed, this will be an excellent addition to the test suite! The foundation is solid, it just needs some cleanup to meet the project's quality standards.

Please let me know if you have any questions about these recommendations!

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

PR Review: E2E Tests for Rotor, Go To Extrema, and Hover Features

Summary

This PR adds comprehensive end-to-end tests for three important MAIDR features: rotor navigation, go-to-extrema functionality, and hover mode settings. Overall, the implementation is well-structured and follows the project's testing patterns. Below are my findings organized by category.


✅ Strengths

Code Quality & Best Practices

  • Excellent Page Object Pattern: The implementation consistently uses the page object pattern with well-organized methods in BasePage and plot-specific classes
  • Strong JSDoc Documentation: All new methods have comprehensive JSDoc comments with @param, @returns, and @throws tags
  • Type Safety: Proper TypeScript usage with explicit type annotations and error handling
  • Consistent Naming: Methods follow camelCase convention and have descriptive names (e.g., moveToNextRotorMode, openGoToExtremaModal)
  • DRY Principle: Shared functionality is properly extracted to BasePage (lines 808-946), making it reusable across all plot types
  • Error Handling: Good use of try-catch blocks with meaningful error messages using custom error classes

Test Coverage

  • Comprehensive Coverage: Tests cover all three features extensively:
    • Rotor navigation (forward/backward cycling, mode transitions)
    • Go-to-extrema (modal open/close, navigation, selection)
    • Hover mode (settings, hover interaction, click interaction)
  • Edge Cases: Tests verify boundary conditions (e.g., cycling through all rotor modes, closing modals multiple ways)
  • Data Validation: Tests properly verify expected data values using the actual MAIDR data structure

⚠️ Issues & Recommendations

1. Code Duplication Across Plot Types

Issue: The rotor navigation and go-to-extrema methods are duplicated across multiple page objects (barplot-page.ts, boxplotHorizontal-page.ts, boxplotVertical-page.ts, etc.). This violates DRY principles.

Files affected:

  • e2e_tests/page-objects/plots/barplot-page.ts:419-726
  • e2e_tests/page-objects/plots/boxplotHorizontal-page.ts:314-565
  • Similar duplications in other plot files

Recommendation: Move these methods to BasePage since they appear to work identically across all plot types. This would:

  • Reduce ~300+ lines of duplicated code per file
  • Make maintenance easier (fix bugs in one place)
  • Follow the existing pattern where shared functionality lives in BasePage

Example refactor:

// In base-page.ts - add these methods once
public async moveToNextRotorMode(): Promise<void> {
  try {
    await this.page.keyboard.down(TestConstants.ALT_KEY);
    await this.page.keyboard.down(TestConstants.SHIFT_KEY);
    await this.pressKey(TestConstants.UP_ARROW_KEY, 'move to next rotor mode');
    await this.page.keyboard.up(TestConstants.SHIFT_KEY);
    await this.page.keyboard.up(TestConstants.ALT_KEY);
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    throw new Error(`Failed to move to next rotor mode: ${errorMessage}`);
  }
}

2. Hardcoded Test Data

Issue: Test cases have hardcoded data values specific to the "tips" dataset (e.g., barplot.spec.ts:402-403, 541-543, 552-554).

// Lines 541-543
expect(currentDataPoint).toContain('Sat');  // Assumes 'Sat' is max
expect(currentDataPoint).toContain('Fri');  // Assumes 'Fri' is min

Recommendation:

  • Extract test data expectations into constants or test fixtures
  • Consider testing with multiple datasets to ensure robustness
  • Make assertions more generic when possible (e.g., verify that max/min navigation works without hardcoding specific values)

3. Magic Numbers in Tests

Issue: Tests use magic numbers without explanation (barplot.spec.ts:624, 639):

await barPlotPage.hoverOnDataPoint(0.3, 0.5);  // What do these numbers represent?

Recommendation: Add constants or comments to clarify:

// Hover on the first bar (approximately 30% from left, center vertically)
const FIRST_BAR_X = 0.3;
const CENTER_Y = 0.5;
await barPlotPage.hoverOnDataPoint(FIRST_BAR_X, CENTER_Y);

4. Incomplete Example HTML Files

Issue: The PR adds 30,131 new lines, with 24 new example HTML files. These appear to be duplicates or variations (e.g., dodged-barplot.html and dodged_barplot.html).

Recommendation:

  • Verify if all example files are necessary
  • If duplicates exist, remove them to reduce repository size
  • Add documentation explaining the purpose of each example file

5. Configuration Change in test-config.ts

Issue: Changed trace mode from 'on-first-retry' to 'retry-with-trace' (line 54).

Question: Is this intentional? The new value doesn't appear to be a valid Playwright configuration option. Valid options are:

  • 'on-first-retry'
  • 'on'
  • 'off'
  • 'retain-on-failure'

Recommendation: Verify this change. If you want traces on retry, use 'on-first-retry' (the original value).

6. Potential Race Condition in Hover Tests

Issue: The hover tests rely on expect.poll() to wait for data to appear, but there's no verification that the correct data point was selected (barplot.spec.ts:627-629).

await expect.poll(async () => {
  return await barPlotPage.getCurrentDataPointInfo();
}).toBeTruthy();  // Only checks that SOME data appears, not the RIGHT data

Recommendation:

await expect.poll(async () => {
  const info = await barPlotPage.getCurrentDataPointInfo();
  return info.includes('expected_value'); // Verify the correct data point
}).toBeTruthy();

7. Missing Accessibility Considerations

Issue: The rotor and go-to-extrema features are accessibility features, but tests don't verify:

  • Screen reader announcements
  • ARIA attributes
  • Keyboard trap prevention
  • Focus management

Recommendation: Consider adding tests that verify:

  • Proper ARIA labels on extrema targets
  • Focus returns to the plot after modal close
  • Rotor mode announcements are accessible

🔒 Security Concerns

No critical security issues identified, but note:

  • The example HTML files inject large amounts of inline JavaScript and data
  • Ensure these examples properly sanitize any user-provided data if they're used as templates

⚡ Performance Considerations

  1. Test Execution Time: With comprehensive tests across 9 plot types, test suite runtime may increase significantly

    • Recommendation: Consider parallelization strategies or selective test execution
  2. Large Example Files: The example HTML files are quite large (1000+ lines each)

    • Recommendation: Consider generating examples programmatically or using templates to reduce duplication

📋 Additional Suggestions

Style Guide Compliance

Follows most style guide rules:

  • 2-space indentation
  • Semicolons present
  • Single quotes for strings
  • Meaningful variable names in camelCase

Potential violations:

  • Some lines exceed 100 characters (e.g., barplot-page.ts:419)
  • Consider running npm run lint:fix to auto-correct

Testing Best Practices

✅ Good use of:

  • beforeAll for data setup
  • beforeEach for page navigation
  • Descriptive test names
  • AAA (Arrange-Act-Assert) pattern

Documentation

  • Consider updating E2E_TESTING.md to document the new test categories (rotor, extrema, hover)
  • Add examples of how to test these features for future contributors

🎯 Required Actions Before Merge

High Priority

  1. ✅ Verify test-config.ts trace configuration is correct
  2. ⚠️ Consider refactoring duplicated code to BasePage
  3. ⚠️ Remove duplicate example files if they exist
  4. ✅ Run npm run lint and fix any violations

Medium Priority

  1. Add constants for magic numbers in tests
  2. Improve hover test assertions to verify correct data points
  3. Extract hardcoded test data to fixtures

Low Priority

  1. Add accessibility verification tests
  2. Document new test categories in E2E_TESTING.md
  3. Consider test execution time optimization

📊 Overall Assessment

Code Quality: ⭐⭐⭐⭐ (4/5)
Test Coverage: ⭐⭐⭐⭐⭐ (5/5)
Documentation: ⭐⭐⭐⭐ (4/5)
Maintainability: ⭐⭐⭐ (3/5 due to code duplication)

Recommendation: Approve with requested changes

This is solid work that significantly improves test coverage for important accessibility features. The main concern is code duplication, which should be addressed to improve long-term maintainability. Once the duplicated methods are refactored to BasePage and the trace configuration is verified, this PR will be in excellent shape for merge.

Great job on the comprehensive test coverage! 🎉

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Pull Request Review - PR #489

Overview

This PR adds comprehensive E2E tests for rotor navigation, goto extrema functionality, and hover mode across multiple plot types. The changes include:

  • 30,131 additions across 48 files
  • New test methods for rotor navigation, extrema navigation, and hover interaction
  • Updates to workflow configuration and trace settings
  • Addition of many HTML example files

Positive Aspects ✅

1. Excellent Code Documentation

  • All new methods include comprehensive JSDoc comments with @param, @returns, and @throws tags
  • Clear, descriptive method names following camelCase convention
  • Consistent documentation style across all page objects

2. Well-Structured Page Object Pattern

  • Proper inheritance from BasePage for shared functionality
  • Logical grouping of methods by feature (Settings Modal, Rotor Navigation, Go To Extrema, Hover Mode)
  • Good use of helper methods in base class to reduce code duplication

3. Consistent Error Handling

  • Type-safe error handling using custom error classes (e.g., BarPlotError, BoxplotHorizontalError)
  • Proper error message formatting with context
  • Appropriate use of try-catch blocks

4. Good Test Constants Organization

  • New constants properly added to TestConstants class
  • Clear naming conventions for all constants
  • Centralized management of selectors and keys

Issues & Concerns 🔴

1. Code Duplication (Critical)

The most significant issue is massive code duplication across plot page objects. The same methods are copy-pasted across:

  • barplot-page.ts
  • boxplotHorizontal-page.ts
  • boxplotVertical-page.ts
  • dodgedBarplot-page.ts
  • heatmap-page.ts
  • histogram-page.ts
  • lineplot-page.ts
  • multiLayer-page.ts
  • multiLineplot-page.ts
  • stackedBarplot-page.ts

Examples of duplicated code blocks:

  • Rotor navigation methods (identical across all files)
  • Go To Extrema methods (identical across all files)
  • Hover mode methods (nearly identical)
  • Settings modal methods (identical across all files)

Recommendation: Move all these methods to base-page.ts since they're already implemented there (lines 808-945). The child classes should inherit these methods rather than re-implementing them.

File reference: /home/runner/work/maidr/maidr/e2e_tests/page-objects/base-page.ts:808-945

2. Inconsistent Error Handling

While error handling is generally good, there are some inconsistencies:

// In base-page.ts:871-878
public async isHoverModeVisible(): Promise<boolean> {
  try {
    const hoverMode = this.page.getByText(TestConstants.SETTINGS_HOVER_MODE);
    const isVisible = await hoverMode.isVisible();
    return isVisible === true; // Redundant comparison
  } catch {
    return false;
  }
}

Issue: The comparison isVisible === true is redundant since isVisible() already returns a boolean.

Recommendation: Simplify to return await hoverMode.isVisible();

3. Potential Race Conditions

// base-page.ts:841-842
const closeButton = this.page.locator('button').filter({ hasText: /^Close$/ });
await closeButton.click();

Issue: No wait for the button to be visible/enabled before clicking. In slower environments, this could lead to flaky tests.

Recommendation: Add explicit waits:

await closeButton.waitFor({ state: 'visible' });
await closeButton.click();

4. Missing Null Safety in SVG Methods

// base-page.ts:902-909
protected async getSvgBoundingBox(svgSelector: string): Promise<{ x: number; y: number; width: number; height: number }> {
  const svg = this.page.locator(svgSelector);
  const boundingBox = await svg.boundingBox();
  if (!boundingBox) {
    throw new Error('Failed to get SVG bounding box');
  }
  return boundingBox;
}

Issue: Generic error message doesn't indicate which SVG element failed or why.

Recommendation:

throw new Error(`Failed to get bounding box for SVG selector: ${svgSelector}. Element may not be visible or loaded.`);

5. Hard-coded Timeout Values

Throughout the code, there are hard-coded timeout values:

  • { timeout: 5000 } in multiple places
  • { timeout: 2000 } in modal close methods

Recommendation: Extract these to constants in TestConstants:

static readonly MODAL_OPEN_TIMEOUT = 5000;
static readonly MODAL_CLOSE_TIMEOUT = 2000;

6. Incomplete PR Description

The PR template checklist is entirely unchecked:

  • I have read the Contributor Guidelines
  • I have performed a self-review
  • I have tested the changes locally
  • I have commented my code
  • I have updated the documentation
  • I have added appropriate unit tests

Action Required: Please complete the PR checklist and provide:

  • Description of changes
  • Related issues
  • Testing evidence (screenshots/recordings recommended)

7. Workflow Configuration Change

-  # pull_request:
-  #   types: [opened, synchronize]
+  pull_request:
+    types: [opened, synchronize]

Question: This enables the audit workflow for all PRs touching examples/** or src/ui/**. Was this intentional? This will now run on every PR affecting those paths.

Recommendation: Document in the PR description why this change was made.

8. Trace Configuration Change

-    trace: 'on-first-retry',
+    trace: 'retain-on-failure',

Impact: This changes when traces are captured. retain-on-failure keeps traces only on final failure, while on-first-retry captures on the first retry attempt.

Recommendation: Document why this change improves the testing experience.

9. Large Number of HTML Example Files

48 HTML files were added/modified in the examples/ directory, many appearing to be duplicates (e.g., dodged-barplot.html and dodged_barplot.html).

Concerns:

  • Are these all necessary for testing?
  • File naming inconsistency (kebab-case vs snake_case)
  • No clear documentation of which examples are used by which tests

Recommendation:

  • Remove duplicate files
  • Standardize naming convention (prefer kebab-case per style guide)
  • Document the purpose of each example file

Performance Considerations ⚡

Parallel Test Execution

The tests appear well-structured for parallel execution with proper page isolation. Good job!

Potential Improvements

Consider adding test tags for better test organization:

test.describe('Rotor Navigation @rotor', () => {
  // tests
});

This would allow running specific test categories: npm run e2e -- --grep @rotor

Security Concerns 🔒

No significant security issues identified. The code:

  • ✅ Doesn't execute arbitrary code
  • ✅ Doesn't expose sensitive information
  • ✅ Uses proper input validation where needed

Test Coverage 📊

What's Covered ✅

  • Rotor mode navigation (cycle through modes)
  • Go To Extrema modal (open/close/navigate/select)
  • Settings modal interactions
  • Hover mode configuration
  • SVG interaction (click/hover)

What Might Be Missing ❓

  • Edge cases: What happens when rotor navigation reaches boundaries?
  • Error states: What if the extrema modal fails to load?
  • Accessibility: Are ARIA attributes properly tested?
  • Integration: Tests for hover mode actually triggering data point selection

Recommendations Summary

High Priority 🔴

  1. Remove code duplication - All methods already in base-page.ts should not be duplicated in child classes
  2. Complete PR checklist - Fill out the description, testing evidence, and checklist
  3. Document workflow changes - Explain audit.yml and trace configuration changes

Medium Priority 🟡

  1. Add explicit waits before button clicks to prevent flaky tests
  2. Extract hard-coded timeouts to constants
  3. Improve error messages with more context
  4. Standardize example file naming and remove duplicates

Low Priority 🟢

  1. Add test tags for better organization
  2. Simplify redundant boolean comparisons
  3. Consider adding more edge case tests

Conclusion

This PR adds valuable test coverage for important features (rotor navigation, extrema navigation, hover mode). The code quality is generally good with excellent documentation and consistent patterns. However, the massive code duplication is a critical issue that should be addressed before merging. Moving the duplicated methods to the base class will:

  • Reduce maintenance burden
  • Prevent inconsistencies
  • Follow DRY principles
  • Improve code maintainability

Once the duplication is resolved and the PR description is completed, this will be a solid addition to the test suite.

Recommendation: Request changes to address code duplication before approval.


Review generated by Claude Code - Automated PR Review

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Pull Request Review - PR #489

Summary

This PR adds comprehensive e2e tests for three new MAIDR features: Rotor Navigation, Go To Extrema, and Hover Mode. The PR includes extensive test coverage across multiple plot types and adds over 30K lines (primarily example HTML files and test infrastructure).

Positive Aspects ✅

1. Excellent Test Coverage

  • Comprehensive test suites for all three new features across 10 different plot types
  • Tests cover both happy paths and edge cases (e.g., cycling through modes, toggling modals)
  • Good use of helper functions to extract and validate data points

2. Well-Structured Page Objects

  • Proper use of the Page Object pattern with inheritance from BasePage
  • Clear separation of concerns with dedicated methods for each feature
  • Good error handling with custom error classes (e.g., BarPlotError)

3. Good Documentation

  • JSDoc comments on most new methods with @param, @returns, and @throws tags
  • Clear test descriptions that explain the expected behavior
  • Constants are well-organized and properly documented

4. Configuration Improvements

  • Re-enabled the audit workflow for examples and UI changes
  • Added build step to e2e workflow (important for ensuring tests run against current code)
  • Changed trace mode to retry-with-trace for better debugging

Issues & Recommendations 🔍

Critical Issues

1. Code Duplication Across Page Objects ⚠️

Location: All plot page objects (barplot, boxplot, lineplot, etc.)

The same 254 lines of code for Rotor, Go To Extrema, and Hover methods are duplicated across 10 different page objects. This violates DRY principles and creates maintenance nightmares.

Example: Lines added to e2e_tests/page-objects/plots/barplot-page.ts:419-731 are nearly identical to those in boxplotHorizontal-page.ts, boxplotVertical-page.ts, etc.

Impact:

  • Bug fixes must be applied to 10 different files
  • Inconsistencies across plot types
  • Harder to maintain and test

Recommendation:
Move these shared methods to BasePage since they're already using this.selectors.rotor and other base selectors. This would reduce ~2,540 lines of duplicated code.

// In BasePage, these methods can be shared by all plot types
public async moveToNextRotorMode(): Promise<void> { ... }
public async openGoToExtremaModal(): Promise<void> { ... }
public async hoverOnDataPoint(relativeX: number, relativeY: number): Promise<void> { ... }

2. Inconsistent Error Handling

Location: e2e_tests/page-objects/plots/boxplotHorizontal-page.ts:299

/**
  /**  // Double JSDoc opening - syntax error
   * Verifies the plot has loaded correctly

This appears to be a typo with duplicate comment markers.

Recommendation: Remove the duplicate /** on line 299.

3. Missing Type Safety in Constants

Location: e2e_tests/utils/constants.ts

Constants like rotor modes are plain strings, which allows typos and doesn't provide autocomplete.

Current:

static readonly ROTOR_DATA_MODE = 'DATA POINT NAVIGATION';

Recommendation: Use enums for better type safety:

export enum RotorMode {
  DATA_POINT = 'DATA POINT NAVIGATION',
  LOWER_VALUE = 'LOWER VALUE NAVIGATION', 
  HIGHER_VALUE = 'HIGHER VALUE NAVIGATION'
}

Code Quality Issues

4. Hardcoded Test Data

Location: e2e_tests/specs/barplot.spec.ts:399-434

Tests contain hardcoded expectations based on the tips dataset (Sat=87, Sun=76, etc.). If example data changes, tests will break.

// Line 402: Hardcoded expectation
expect(firstPoint).toContain('Sat');

Recommendation: Extract test data from the maidr-data attribute (which you're already doing in beforeAll) and use that for assertions instead of hardcoding values.

5. Magic Numbers in Test Waits

Location: e2e_tests/specs/barplot.spec.ts:590

await page.waitForTimeout(500);

Recommendation: Use constants from TestConstants instead of magic numbers, or better yet, use Playwright's built-in waiting mechanisms:

await page.waitForSelector(TestConstants.GO_TO_EXTREMA_MODAL, { state: 'hidden' });

6. Inconsistent Method Naming

Location: Multiple page objects

Some methods use move prefix, others use navigate:

  • moveToNextRotorMode()
  • navigateToRotorMode()

Recommendation: Standardize on one naming convention. Based on existing code, moveTo* seems more common.

7. Potential Race Conditions in Settings Modal Tests

Location: e2e_tests/page-objects/base-page.ts:838-862

The closeSettingsModalWithButton and saveAndCloseSettingsModal methods click buttons but only wait 2 seconds for the modal to disappear. This could be flaky in slow CI environments.

Recommendation: Increase timeout or make it configurable:

await expect(this.page.locator(this.selectors.settingsModal))
  .not.toBeVisible({ timeout: 5000 }); // Increase from 2000

Best Practices & Architecture

8. Missing Test for Accessibility

The new hover mode feature affects accessibility, but there are no tests verifying:

  • ARIA labels are properly set
  • Keyboard focus management works correctly
  • Screen reader announcements are triggered

Recommendation: Add accessibility-focused tests, especially for the settings modal radio buttons.

9. Large Example HTML Files

The PR adds ~27K lines of example HTML files. Many appear to be duplicates with slightly different names:

  • dodged-barplot.html and dodged_barplot.html
  • stacked-barplot.html and stacked_bar.html
  • boxplot-horizontal.html and horizontal-boxplot.html

Recommendation:

  • Consolidate duplicate examples
  • Consider if all examples need to be in the repo or if they could be generated
  • Add a comment explaining why duplicates exist if they serve different purposes

10. Test Organization

Location: All test spec files

Tests are well-organized, but some describe blocks could be more granular. For example, "Rotor Navigation" could be split into:

  • "Rotor Navigation - Mode Switching"
  • "Rotor Navigation - Value Navigation"

Recommendation: Consider further test organization for better test reporting and selective test execution.


Performance Considerations

11. beforeAll Context Management

Location: All spec files

Each test file creates a new browser context in beforeAll to extract MAIDR data, then closes it. This data extraction happens once per test file.

Recommendation: This is acceptable, but consider documenting why this approach is used vs. extracting data in beforeEach.

12. Sequential Test Execution

Many navigation tests use loops that execute sequentially:

for (let i = 0; i <= dataLength; i++) {
  await barPlotPage.moveToNextDataPoint();
}

Recommendation: This is fine for testing, but consider adding a test that validates bulk navigation is efficient (no memory leaks, reasonable performance).


Security Concerns

13. No Input Validation on Relative Coordinates

Location: e2e_tests/page-objects/base-page.ts:914-943

Methods hoverOnSvgPoint and clickOnSvgPoint accept relativeX and relativeY but don't validate they're in the 0-1 range.

Recommendation: Add parameter validation:

if (relativeX < 0 || relativeX > 1 || relativeY < 0 || relativeY > 1) {
  throw new Error('Relative coordinates must be between 0 and 1');
}

Testing Gaps

14. Missing Error Scenario Tests

Current tests focus on happy paths. Consider adding tests for:

  • What happens when Go To Extrema modal is opened with no data
  • Rotor navigation at data boundaries
  • Hover mode with invalid coordinates
  • Settings changes without saving (discard behavior)

15. No Tests for Multi-Layer Plots

While there's a multiLayer-page.ts with the new methods, there are no specific tests in multiLayer.spec.ts for how rotor/extrema work across layers.

Recommendation: Add tests verifying these features work correctly in multi-layer contexts.


Minor Issues

  1. Inconsistent String Quoting: Mix of single and double quotes in selectors (minor, but style guide specifies single quotes)
  2. Unused Imports: Some imports may be unused (should run linter)
  3. Comment Formatting: Some JSDoc comments missing periods at the end
  4. File Naming: Mix of kebab-case and snake_case in examples folder

Testing Recommendations

Before Merging:

  1. Fix the critical duplication issue - This should be addressed before merging
  2. Fix the JSDoc syntax error in boxplotHorizontal-page.ts:299
  3. Run the full e2e test suite to ensure all tests pass
  4. Check for linting errors with the project's linter

Future Improvements:

  1. Add visual regression tests for the new modals
  2. Consider adding performance benchmarks for rotor navigation
  3. Add integration tests that combine multiple features
  4. Document the test data expectations in a separate file

Conclusion

This is a substantial and well-structured PR that adds valuable test coverage for three important accessibility features. The code quality is generally good with proper use of TypeScript, page objects, and testing patterns.

However, the code duplication across page objects is a significant maintainability concern that should be addressed before merging. Moving shared functionality to BasePage would reduce the PR size by ~2,500 lines and make future maintenance much easier.

Recommendation: Request Changes

Priority Fixes:

  1. Refactor duplicated rotor/extrema/hover methods into BasePage
  2. Fix JSDoc syntax error in boxplotHorizontal-page.ts
  3. Address hardcoded test data dependencies

Optional Improvements:
4. Consolidate duplicate example HTML files
5. Add type safety with enums for mode constants
6. Improve error handling and input validation

Great work on the comprehensive test coverage! Once the duplication is addressed, this will be an excellent addition to the project. 🎉


Review conducted following project's architectural guidelines (UI → ViewModel → Service → Core) and style guide requirements.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Code Review - PR #489: E2E Tests for Rotor, Go To Extrema, and Hover Features

Thank you for this substantial contribution! This PR adds comprehensive E2E test coverage for three important features: rotor navigation, go to extrema functionality, and hover mode. Here's my detailed review:


✅ Strengths

1. Comprehensive Test Coverage

  • Excellent addition of tests across multiple plot types (barplot, lineplot, boxplot horizontal/vertical, dodged barplot, heatmap, histogram, stacked barplot, multi-lineplot, multi-layer)
  • Well-structured test organization with clear test descriptions
  • Good use of helper functions (setupBarPlotPage, getBarPlotDataLength, etc.)

2. Code Organization

  • Follows the established page object pattern consistently
  • Proper separation of concerns (page objects, specs, constants, utils)
  • Good adherence to the style guide (JSDoc comments, TypeScript typing, error handling)

3. Documentation

  • Excellent JSDoc documentation for all new methods
  • Clear @param, @returns, and @throws tags
  • Method descriptions are clear and helpful

4. Workflow Improvements

  • Good fix in .github/workflows/audit.yml and .github/workflows/e2e.yml to add npm run build before running tests
  • Re-enabled the audit workflow for examples and UI changes

🐛 Potential Issues

1. Code Duplication (High Priority)

The new methods added to page objects are nearly identical across all plot types. This violates DRY principles and creates a maintenance burden.

Issue: Methods like moveToNextRotorMode(), openGoToExtremaModal(), hoverOnDataPoint(), etc. are duplicated in:

  • barplot-page.ts (310 lines added)
  • boxplotHorizontal-page.ts (251 lines added)
  • boxplotVertical-page.ts (251 lines added)
  • dodgedBarplot-page.ts (251 lines added)
  • heatmap-page.ts (251 lines added)
  • histogram-page.ts (251 lines added)
  • lineplot-page.ts (251 lines added)
  • multiLayer-page.ts (252 lines added)
  • multiLineplot-page.ts (251 lines added)
  • stackedBarplot-page.ts (251 lines added)

Recommendation: These common methods should be moved to base-page.ts since they already exist there for some features. I noticed you added:

  • openSettingsModal()
  • closeSettingsModalWithButton()
  • saveAndCloseSettingsModal()
  • isHoverModeVisible()
  • selectHoverMode()
  • getSvgBoundingBox()
  • hoverOnSvgPoint()
  • clickOnSvgPoint()

to base-page.ts (139 lines), which is the right approach. All the rotor and go-to-extrema methods should also be in base-page.ts and then each plot-specific page object can override them if needed for plot-specific behavior.

Impact: This would reduce ~2,200 lines of duplicated code to ~300 lines in the base class.

2. Missing Error Handling in Some Areas

In getExtremaTargets() method (repeated across all plot pages):

public async getExtremaTargets(): Promise<string[]> {
  try {
    const targets: string[] = [];
    let index = 0;

    while (true) {  // ⚠️ Infinite loop without bounds check
      const targetElement = await this.page.$(`#extrema-target-${index}`);
      if (!targetElement) {
        break;
      }
      const text = await targetElement.textContent();
      targets.push(text || '');  // ⚠️ Empty string pushed on null
      index++;
    }
    return targets;
  } catch (error) {
    // ...
  }
}

Recommendations:

  • Add a maximum iteration limit to prevent infinite loops
  • Consider logging when textContent returns null
  • Add validation that at least some targets were found

3. Inconsistent Error Handling in Settings Modal Methods

In base-page.ts:842-843:

public async closeSettingsModalWithButton(): Promise<void> {
  try {
    const closeButton = this.page.locator('button').filter({ hasText: /^Close$/ });
    await closeButton.click();
    await expect(this.page.locator(this.selectors.settingsModal)).not.toBeVisible({ timeout: 2000 });

Issue: Using expect inside a page object method is unusual. Typically, page objects perform actions and return values, while tests handle assertions.

Recommendation: Consider splitting into:

  • clickCloseButton() - performs the click
  • Test file does the visibility assertion

Or at minimum, make the timeout configurable.

4. Trace Configuration Change

In e2e_tests/config/test-config.ts:54:

- trace: 'on-first-retry',
+ trace: 'retry-with-trace',

Question: Was this intentional? According to Playwright docs:

  • on-first-retry - Record trace on first retry only
  • retry-with-trace - Record trace when retrying with trace

This might generate more trace files. Please confirm this is the desired behavior.

5. Removed Comment in boxplotHorizontal-page.ts:314

-  /**
   /**
    * Verifies the plot has loaded correctly

Minor: Duplicate JSDoc comment start removed. This is good but might indicate a merge conflict or editing artifact.


🔍 Code Quality Observations

1. Type Safety

✅ Good use of TypeScript types and interfaces
✅ Proper error typing with custom error classes
✅ Clear return types on all methods

2. Naming Conventions

✅ Follows camelCase consistently
✅ Method names are descriptive and action-oriented
✅ Constants use SCREAMING_SNAKE_CASE appropriately

3. Example HTML Files (30,137 additions)

The PR includes 49 changed files with many being example HTML files. These appear to be regenerated or updated plot examples.

Concern: This makes the PR very large (30,137 additions). Consider if:

  • These are all necessary for the PR
  • They could be in a separate PR
  • They're generated files that should be gitignored

🎯 Test Coverage Assessment

✅ Well Covered:

  • Rotor navigation mode switching
  • Go to extrema modal interactions
  • Hover mode settings
  • Keyboard navigation in all modes

⚠️ Potential Gaps:

  1. Edge Cases:

    • What happens if rotor mode is activated on an empty plot?
    • What if extrema targets are identical (all same value)?
    • Hover on invalid coordinates?
  2. Error States:

    • No tests for error scenarios (missing data, invalid selectors)
    • No tests for concurrent mode changes
  3. Accessibility:

    • Are ARIA attributes correct?
    • Screen reader announcements tested?

🔒 Security Considerations

✅ No obvious security issues
✅ No user input being directly injected
✅ Proper use of parameterized selectors
✅ No use of eval or dangerouslySetInnerHTML


⚡ Performance Considerations

1. Test Execution Time

With 10 plot types × ~3 new test categories, this adds significant test time.

Suggestions:

  • Consider if all plot types need identical tests (some might be redundant)
  • Use test.describe.configure({ mode: 'parallel' }) where safe
  • Consider splitting into different test files for better parallelization

2. Selector Performance

Multiple uses of:

const targetElement = await this.page.$(`#extrema-target-${index}`);

Suggestion: Consider using page.locator().all() instead of looping with individual queries:

const targets = await this.page.locator('[id^="extrema-target-"]').allTextContents();

📋 Checklist Review

Looking at the PR template checklist - most items are unchecked. Please ensure:

  • Self-review completed
  • Manual testing done per ManualTestingProcess.md
  • Code commented (✅ this is done well!)
  • Documentation updated (check if needed)
  • Unit tests added (these are E2E tests, but appropriate)

🎯 Recommendations Summary

High Priority:

  1. Refactor duplicated methods to base-page.ts - This will reduce ~2,200 lines of duplication
  2. Add bounds checking to getExtremaTargets() loop
  3. Clarify the trace configuration change - Is retry-with-trace intentional?
  4. Review example HTML file changes - Confirm these are all necessary

Medium Priority:

  1. Move assertions out of page object methods - Or make timeouts configurable
  2. Add edge case tests - Empty data, identical values, invalid inputs
  3. Consider test parallelization - To manage increased test count
  4. Add error scenario tests - What happens when things go wrong?

Low Priority:

  1. Optimize selector usage - Use bulk queries instead of loops
  2. Add accessibility validation tests - ARIA attributes, announcements

📝 Final Verdict

This is a solid PR that significantly improves test coverage for important accessibility features. The code quality is high, documentation is excellent, and it follows established patterns.

Main blocker: The massive code duplication needs to be addressed before merge. Moving common methods to base-page.ts will make this code much more maintainable.

Once the duplication issue is resolved and the other high-priority items are addressed, this will be ready to merge.

Estimated refactoring effort: 2-3 hours to move methods to base class and update all page objects to use inherited methods.


Great work on the comprehensive testing! Please let me know if you have questions about any of these suggestions.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in model-related files

This PR contains changes to files that affect the model layer and unit tests. Before merging, please ensure:

  1. Run the unit tests locally:

    npm run test
  2. Update tests if necessary

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Pull Request Review: E2E Tests for Rotor, Go To Extrema, and Hover Features

Summary

This PR adds comprehensive end-to-end tests for three important accessibility features (rotor navigation, go to extrema modal, and hover mode) across multiple plot types. The implementation follows good testing practices with well-structured page objects and test specifications.

Strengths ✅

1. Excellent Test Architecture

  • Page Object Pattern: Properly implements the Page Object Model with clear separation of concerns
  • Code Reuse: Base page methods are well-designed and reusable across multiple plot types
  • Constants Management: Good use of TestConstants class for centralized test data
  • Type Safety: Proper TypeScript usage with typed parameters and return values

2. Comprehensive Test Coverage

  • Tests cover all major plot types: barplot, boxplot (horizontal/vertical), dodged barplot, heatmap, histogram, lineplot, multilineplot, stacked barplot, and multilayer
  • Each plot type includes tests for:
    • Rotor navigation (forward/backward cycling, mode switching)
    • Go To Extrema modal (open/close, navigation, selection)
    • Hover mode settings (off, hover, click modes)
  • Good edge case testing (e.g., modal visibility, mode cycling)

3. Well-Documented Code

  • Excellent JSDoc comments explaining method parameters, return types, and error conditions
  • Clear test descriptions that explain what is being tested
  • Good use of descriptive variable and method names

4. Proper Error Handling

  • Try-catch blocks with meaningful error messages
  • Custom error types (e.g., BarPlotError, BoxplotHorizontalError)
  • Good use of instanceof Error checks for type-safe error handling

5. Workflow Improvements

  • Re-enabled the audit workflow for PR changes in examples/ and src/ui/ directories
  • Added necessary build steps to workflows to ensure maidr.js is available for tests
  • Changed trace mode to retain-on-failure for better debugging

Issues & Concerns ⚠️

1. Code Duplication (High Priority)

Severity: Medium - Maintenance burden

The same ~250 lines of code for rotor navigation, go to extrema, and hover mode methods are duplicated across 9 different page object files. This violates the DRY principle and creates significant maintenance issues.

Files affected:

  • barplot-page.ts
  • boxplotHorizontal-page.ts
  • boxplotVertical-page.ts
  • dodgedBarplot-page.ts
  • heatmap-page.ts
  • histogram-page.ts
  • lineplot-page.ts
  • multiLineplot-page.ts
  • stackedBarplot-page.ts

Recommendation:
These methods should be moved to the BasePage class (they're already added there in this PR at lines 807-943). Remove the duplicate implementations from individual page classes and rely on inheritance. The methods in BasePage are already public and accessible to all child classes.

Example refactor:

// In barplot-page.ts - REMOVE these duplicate methods:
// - moveToNextRotorMode()
// - moveToPrevRotorMode()
// - getCurrentRotorMode()
// - openGoToExtremaModal()
// - etc.

// These are already available via inheritance from BasePage

2. Missing Documentation Cleanup

Severity: Low

In boxplotHorizontal-page.ts line 299, there's a duplicate JSDoc comment:

  /**
  /**
   * Verifies the plot has loaded correctly

Recommendation: Remove the duplicate comment marker.

3. HTML Example Files

Severity: Low - File size concern

The PR adds 30,145 lines across 23 HTML example files. While these are necessary for testing, some observations:

  • Many files appear to be duplicates with slight naming variations (e.g., dodged-barplot.html vs dodged_barplot.html, multiline_plot.html vs multi-lineplot.html)
  • Total addition: 30,145 lines vs 28 deletions

Recommendation:

  • Verify if duplicate-named files are intentional
  • Consider if all variations are necessary or if some can be consolidated
  • Ensure these files are properly .gitignored if they're generated artifacts

4. Potential Test Flakiness

Severity: Low

Some tests rely on hard-coded wait times and polling intervals:

await this.page.waitForSelector(TestConstants.GO_TO_EXTREMA_MODAL, { timeout: 5000 });

Recommendation:

  • Current implementation is acceptable, but monitor for flakiness in CI
  • Consider adding retry logic if tests become unstable
  • The use of retain-on-failure for traces will help diagnose issues

5. Source Code Change

Severity: Low

In src/model/plot.ts, 10 lines were removed (blank lines and error handling). The changes appear to be code cleanup:

  • Removed redundant blank lines
  • Simplified error handling in the highlight getter

Recommendation: Verify this change is intentional and doesn't affect error handling behavior.

Performance Considerations ✅

Good practices:

  • Tests use beforeAll to load data once instead of per-test
  • Proper cleanup with context.close()
  • Efficient selectors and wait strategies
  • No apparent performance issues

Security Considerations ✅

No security concerns identified:

  • Tests use proper Playwright security practices
  • No hardcoded credentials or sensitive data
  • No unsafe eval or injection risks
  • HTML examples use standard SVG/JavaScript

Test Coverage Assessment

Coverage is comprehensive for the three features being tested:

  • ✅ Rotor navigation modes
  • ✅ Go To Extrema modal interactions
  • ✅ Hover mode settings
  • ✅ Multiple plot types
  • ✅ Edge cases and error conditions

Missing (acceptable for this PR scope):

  • Integration tests for rotor + extrema combinations
  • Performance tests for large datasets
  • Accessibility tests with actual screen readers

Recommendations Summary

Must Fix Before Merge:

  1. Remove code duplication - The 9 plot page files should use inherited methods from BasePage instead of duplicating them

Should Fix:

  1. Clean up duplicate JSDoc comment in boxplotHorizontal-page.ts:299
  2. Verify necessity of duplicate HTML example files
  3. Confirm intentionality of src/model/plot.ts changes

Nice to Have:

  1. Add integration tests combining multiple features
  2. Document test data sources (e.g., "tips" dataset with Sat=87, Sun=76, etc.)

Checklist Review

Based on the PR template, the contributor should verify:

  • Self-review completed and code follows standards
  • Local testing completed per ManualTestingProcess.md
  • Code commented in hard-to-understand areas ✅ (Good documentation)
  • Documentation updated (if applicable)
  • Unit tests added ✅ (E2E tests added)

Final Verdict

APPROVE with minor changes requested

This is a high-quality PR that adds valuable test coverage for important accessibility features. The test architecture is solid, documentation is excellent, and the implementation follows best practices. The main concern is code duplication that can be easily resolved by removing the duplicate methods from individual page classes.

The PR significantly improves the project's test coverage and will help prevent regressions in critical accessibility features.

Estimated effort to address issues: 1-2 hours


Review conducted using repository's CONTRIBUTING.md guidelines for TypeScript, testing best practices, and conventional commits.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in examples or UI directory

This PR contains changes to files in the examples/ or src/ui/ directories. Before merging, please ensure:

  1. Run the e2e tests locally:

    npm run e2e
  2. Verify that all examples still work as expected

  3. Update any relevant documentation if needed

If you need help running the tests, please refer to our testing documentation.

@github-actions

Copy link
Copy Markdown

⚠️ Changes detected in model-related files

This PR contains changes to files that affect the model layer and unit tests. Before merging, please ensure:

  1. Run the unit tests locally:

    npm run test
  2. Update tests if necessary

@claude

claude Bot commented Dec 16, 2025

Copy link
Copy Markdown

Pull Request Review - PR #489

Overview

This PR adds comprehensive E2E tests for rotor navigation, go-to-extrema functionality, and hover mode features. It also includes workflow fixes to ensure tests run properly in CI. Overall, this is a valuable addition to the test suite with 30,147 additions across test infrastructure and HTML examples.


✅ Strengths

1. Comprehensive Test Coverage

  • Excellent addition of tests for three important features: rotor navigation, go-to-extrema, and hover mode
  • Tests cover multiple plot types (barplot, boxplot, heatmap, histogram, lineplot, etc.)
  • Good use of the Page Object pattern for maintainability

2. Workflow Improvements

  • Re-enabled the audit workflow for PR validation (.github/workflows/audit.yml)
  • Added necessary build steps to both audit.yml and e2e.yml workflows
  • Changed trace mode to retain-on-failure for better debugging

3. Code Organization

  • Well-structured test helpers and utility functions
  • Clear separation of concerns with dedicated page objects
  • Good JSDoc documentation for new methods

⚠️ Issues & Concerns

1. Code Duplication (Critical)

The most significant issue is massive code duplication across page objects. Nearly identical methods are copy-pasted across all plot types:

Duplicated methods across 9+ files:

  • moveToNextRotorMode() / moveToPrevRotorMode() / getCurrentRotorMode()
  • openGoToExtremaModal() / closeGoToExtremaModal() / isGoToExtremaModalVisible()
  • getExtremaTargets() / getSelectedExtremaTarget() / goToMaximum() / goToMinimum()
  • Settings modal methods (openSettingsModal(), closeSettingsModalWithButton(), etc.)
  • Hover methods (hoverOnDataPoint(), clickOnDataPoint())

Files affected:

  • e2e_tests/page-objects/plots/barplot-page.ts (+310 lines)
  • e2e_tests/page-objects/plots/boxplotHorizontal-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/boxplotVertical-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/dodgedBarplot-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/heatmap-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/histogram-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/lineplot-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/multiLayer-page.ts (+252 lines)
  • e2e_tests/page-objects/plots/multiLineplot-page.ts (+251 lines)
  • e2e_tests/page-objects/plots/stackedBarplot-page.ts (+251 lines)

Recommendation:
The new methods added to BasePage (lines 808-946) already demonstrate the correct approach. ALL the duplicated rotor, extrema, and hover methods should be moved to BasePage and inherited by the plot-specific pages. This would reduce the PR size by ~2,500 lines and make maintenance much easier.

Suggested refactoring:

// In BasePage, add all common methods:
// - Rotor navigation methods (moveToNextRotorMode, etc.)
// - Go to extrema methods (openGoToExtremaModal, etc.)
// - Already done: Settings modal and hover methods ✓

// In plot-specific pages, only keep plot-specific overrides if needed

2. Missing Documentation in PR Description

The PR description is completely empty - only the template remains. This makes it very difficult to understand:

  • What features are being tested
  • Why the workflow changes were needed
  • What the expected behavior is
  • How to manually test these features

Recommendation: Fill out the PR template with:

  • Description of the rotor, extrema, and hover features being tested
  • Related issues (if any)
  • List of changes made
  • Manual testing instructions
  • Checklist completion

3. Source Code Changes Not Explained

There's a change to src/model/plot.ts (-13/+3 lines) that:

  • Removes/refactors code in the actual application
  • Is not mentioned in commit messages or PR description
  • Appears unrelated to test additions

File: src/model/plot.ts (lines 245-252)

Recommendation: This change should either:

  1. Be explained in the PR description
  2. Be split into a separate PR if it's a bug fix
  3. Be reverted if it was accidental

4. Test Configuration Change Needs Justification

// e2e_tests/config/test-config.ts
- trace: 'on-first-retry',
+ trace: 'retain-on-failure',

While this change is reasonable, the commit message "chore: constants in test config" doesn't explain why. This increases storage/artifact size in CI.

Recommendation: Document in PR description why this change was necessary.

5. Large Number of HTML Example Files

The PR includes massive HTML files (many over 1000 lines):

  • examples/facet_barplot.html (1,415 lines)
  • examples/multipanel.html (1,563 lines)
  • examples/scatter_plot.html (1,907 lines)
  • examples/smoothplot.html (4,383 lines!)
  • Many others...

Questions:

  • Are these auto-generated or hand-written?
  • Should they be in version control or generated during build?
  • Could they reference a shared maidr.js instead of including inline scripts?

Recommendation: Consider whether these should be:

  1. Auto-generated from data
  2. Stored in a test fixtures directory
  3. Minimized/optimized

6. Inconsistent Error Types

Some plot pages use custom errors (e.g., BarPlotError, BoxplotHorizontalError), while BasePage uses generic Error.

Recommendation: Be consistent - either use custom errors everywhere or use generic errors. Since the errors are caught and re-thrown with context, generic Error is probably fine.

7. Minor: Duplicate HTML Files

Several HTML files appear to be duplicates with different naming conventions:

  • dodged-barplot.html and dodged_barplot.html
  • stacked-barplot.html and stacked_bar.html
  • boxplot-horizontal.html and horizontal-boxplot.html
  • etc.

Recommendation: Standardize on one naming convention (suggest kebab-case: dodged-barplot.html).


🔒 Security Considerations

✅ No security concerns identified. The code:

  • Does not handle user input
  • Does not make external API calls
  • Only performs UI testing operations
  • Uses safe Playwright APIs

🎯 Performance Considerations

Potential Issues:

  1. CI Build Time: The large number of HTML files and duplicate code may slow down CI
  2. Test Execution: New tests add 9+ test suites, which will increase E2E test runtime
  3. Artifact Size: retain-on-failure trace mode will increase artifact storage

Recommendations:

  • Consider running some tests in parallel if not already doing so
  • Monitor CI execution time after merge
  • Consider splitting tests across multiple jobs if runtime becomes problematic

📝 Best Practices & Code Quality

Good Practices Observed:

✅ Consistent use of TypeScript types
✅ Proper error handling with try-catch blocks
✅ Clear method names and documentation
✅ Separation of concerns (page objects, specs, utilities)
✅ Use of constants for maintainability

Areas for Improvement:

DRY Principle Violation: Massive code duplication (see Issue #1)
PR Documentation: Empty PR description
Commit Messages: Some commits lack detail ("chore: lint", "chore: test reason for failure")
File Naming: Inconsistent naming conventions for HTML files


🧪 Test Coverage Assessment

What's Tested:

✅ Rotor navigation (next/previous modes, navigation within modes)
✅ Go-to-extrema modal (open, close, navigate, select)
✅ Hover mode (hover on data points, click on data points)
✅ Settings modal interaction
✅ Multiple plot types covered

What Could Be Tested:

  • Edge cases (what happens when rotor reaches boundaries?)
  • Error states (what if extrema modal fails to load?)
  • Accessibility features (keyboard navigation, screen reader compatibility)
  • Integration between features (e.g., using rotor + extrema together)

📋 Checklist Items

Based on the PR template, here's the status:

  • ❌ PR description filled out
  • ❓ Contributor Guidelines read
  • ❓ Self-review performed
  • ❓ Local testing completed
  • ❓ Code commented (hard-to-understand areas)
  • ❌ Documentation updated (workflow changes not documented)
  • ❓ Unit tests added (E2E tests added, but are unit tests needed?)

🎬 Action Items

Critical (Must Address Before Merge):

  1. Refactor duplicated code - Move common methods to BasePage
  2. Fill out PR description - Explain what, why, and how
  3. Explain src/model/plot.ts changes - Or revert if unintended

Recommended (Should Address):

  1. Document trace config change rationale
  2. Standardize HTML file naming conventions
  3. Add comments explaining the purpose of large HTML files
  4. Improve commit messages to be more descriptive

Nice to Have:

  1. Consider optimizing/generating HTML example files
  2. Add edge case tests for new features
  3. Add integration tests combining multiple features

💡 Summary

This PR makes a valuable contribution to the test suite by adding comprehensive coverage for important UI features. However, it suffers from a critical code duplication issue that adds ~2,500 unnecessary lines and will make future maintenance difficult.

Recommendation: Request changes to address code duplication before merging. The refactoring should be straightforward since BasePage already demonstrates the correct pattern.

The workflow fixes and test infrastructure improvements are solid, but the PR needs better documentation to help reviewers and future contributors understand the changes.


Review Status: ⚠️ Changes Requested

Priority: Address code duplication (#1) and PR documentation (#2) before merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant