### Plan 1. **Add Detailed Accessibility Tests for Keyboard Navigation:** - Test keyboard navigation for form inputs, buttons, and lightbox. - Ensure interactive elements are focusable and navigable via the keyboard. 2. **Optimize the CI/CD Pipeline:** - Use caching to speed up dependency installation. - Parallelize test execution if possible. ### Complete Code #### JavaScript Unit Tests (using Jest and jest-axe) Install necessary dependencies: ```sh npm install --save-dev jest jest-axe ``` Accessibility tests using `jest-axe` and keyboard navigation tests: ```javascript // __tests__/accessibility.test.js const { JSDOM } = require('jsdom'); const { axe, toHaveNoViolations } = require('jest-axe'); expect.extend(toHaveNoViolations); describe('Accessibility Tests', () => { let dom; let document; beforeEach(() => { dom = new JSDOM(`

Welcome to eBook for Enjoyment

About Us

Our Books

Book 1

Contact Us

Please fill in all fields correctly.
Thank you! Your message has been sent.
Oops! Something went wrong. Please try again.
Sending...
`, { url: "http://localhost" }); document = dom.window.document; }); test('should have no accessibility violations', async () => { const results = await axe(document); expect(results).toHaveNoViolations(); }); test('should have appropriate ARIA roles and attributes', () => { const banner = document.querySelector('[role="banner"]'); const navigation = document.querySelector('[role="navigation"]'); const regions = document.querySelectorAll('[role="region"]'); const form = document.querySelector('[role="form"]'); const liveRegions = document.querySelectorAll('[aria-live="polite"]'); const requiredFields = document.querySelectorAll('[aria-required="true"]'); expect(banner).not.toBeNull(); expect(navigation).not.toBeNull(); expect(regions.length).toBeGreaterThan(0); expect(form).not.toBeNull(); expect(liveRegions.length).toBeGreaterThan(0); expect(requiredFields.length).toBeGreaterThan(0); }); test('buttons should have appropriate ARIA labels', () => { const buttons = document.querySelectorAll('button'); buttons.forEach(button => { expect(button.getAttribute('aria-label')).not.toBeNull(); }); }); test('form inputs should have appropriate ARIA attributes', () => { const inputs = document.querySelectorAll('input, textarea'); inputs.forEach(input => { expect(input.hasAttribute('aria-required')).toBe(true); expect(input.getAttribute('aria-required')).toBe('true'); }); }); test('lightbox should have ARIA attributes', () => { const lightbox = document.getElementById('lightbox'); const closeBtn = document.querySelector('.close'); const lightboxImg = document.getElementById('lightbox-img'); const lightboxCaption = document.getElementById('lightbox-caption'); expect(lightbox.getAttribute('aria-label')).toBe('Image Lightbox'); expect(closeBtn.getAttribute('aria-label')).toBe('Close Lightbox'); expect(lightboxImg.getAttribute('aria-live')).toBe('polite'); expect(lightboxCaption.getAttribute('aria-live')).toBe('polite'); }); test('should allow keyboard navigation for form inputs', () => { const nameInput = document.getElementById('name'); const emailInput = document.getElementById('email'); const messageTextarea = document.getElementById('message'); const submitButton = document.querySelector('button[type="submit"]'); nameInput.focus(); expect(document.activeElement).toBe(nameInput); nameInput.dispatchEvent(new dom.window.KeyboardEvent('keydown', { key: 'Tab' })); expect(document.activeElement).toBe(emailInput); emailInput.dispatchEvent(new dom.window.KeyboardEvent('keydown', { key: 'Tab' })); expect(document.activeElement).toBe(messageTextarea); messageTextarea.dispatchEvent(new dom.window.KeyboardEvent('keydown', { key: 'Tab' })); expect(document.activeElement).toBe(submitButton); }); test('should allow keyboard navigation for lightbox', () => { const img = document.querySelector('.book-item img'); const lightbox = document.getElementById('lightbox'); const closeBtn = document.querySelector('.close'); img.focus(); img.dispatchEvent(new dom.window.KeyboardEvent('keydown', { key: 'Enter' })); expect(lightbox.style.display).toBe('block'); expect(document.activeElement).toBe(closeBtn); closeBtn.dispatchEvent(new dom.window.KeyboardEvent('keydown', { key: 'Enter' })); expect(lightbox.style.display).toBe('none'); expect(document.activeElement).toBe(img); }); }); ``` #### GitHub Actions CI/CD Pipeline with Notifications and Optimizations Create a GitHub Actions workflow file: ```yaml # .github/workflows/ci.yml name: CI on: push: branches: - main pull_request: branches: - main jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [14, 16] steps: - name: Checkout repository uses: actions/checkout@v2 - name: Set up Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - name: Cache Node.js modules uses: actions/cache@v2 with: path: ~/.npm key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }} restore-keys: | ${{ runner.os }}-node-${{ matrix.node-version }}- - name: Install dependencies run: npm install - name: Run tests run: npm test notify: needs: test runs-on: ubuntu-latest if: failure() steps: - name: Send email notification uses: dawidd6/action-send-mail@v3 with: server_address: smtp.example.com server_port: 587 username: ${{ secrets.EMAIL_USERNAME }} password: ${{ secrets.EMAIL_PASSWORD }} subject: GitHub Actions Job Failed to: you@example.com from: github-actions@example.com body: The CI/CD pipeline failed. Please check the logs for more details. ``` Make sure to add `EMAIL_USERNAME` and `EMAIL_PASSWORD` to your GitHub secrets. ### Running Tests To run the tests, ensure you have Jest and jest-axe set up in your project: 1. Install Jest and jest-axe: ```sh npm install --save-dev jest jest-

Comments

Popular posts from this blog