<commit_before>import path from 'path';
import { spawnSync } from 'child_process';

describe('WAI ARIA Spec', () => {
    beforeEach(async () => {
        await page.goto(`file:${path.resolve(__dirname, 'dist/index.html')}`);
    });

    describe('Canary tests', () => {
        it('Loads the Cypress Testing Sandbox', async () => {
            const title = await page.evaluate(() => document.title);
            expect(title).toBe(
                'React Accessible Accordion - Integration Test Sandbox',
            );
        });
        it('has rendered the "classic accordion" example', async () => {
            const qtyClassicAccordion = await page.evaluate(
                () => document.querySelectorAll('#classic-accordion').length,
            );
            expect(qtyClassicAccordion).toEqual(1);
        });
    });

    describe('Chrome Accessibility Tree', () => {
        it('matches snapshots', async () => {
            expect(await page.accessibility.snapshot()).toMatchSnapshot();
        });
    });

    describe('Keyboard Interaction', () => {
        describe('Enter or Space', () => {
            it('When focus is on the accordion header for a collapsed panel, expands the associated panel. If the implementation allows only one panel to be expanded, and if another panel is expanded, collapses that panel.', async () => {
                const headingHandles = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                expect(headingHandles.length).toEqual(3);

                const firstHeadingHandle = headingHandles[0];
                const secondHeadingHandle = headingHandles[1];

                function evaluateIsExpanded(headingHandle) {
                    return page
                        .evaluate(
                            heading => heading.getAttribute('aria-expanded'),
                            headingHandle,
                        )
                        .then(ariaExpanded => ariaExpanded === 'true');
                }

                // ENTER key
                await firstHeadingHandle.focus();
                expect(await evaluateIsExpanded(firstHeadingHandle)).toEqual(
                    false,
                );
                await page.keyboard.press('Enter');
                expect(await evaluateIsExpanded(firstHeadingHandle)).toEqual(
                    true,
                );

                // SPACE key
                await secondHeadingHandle.focus();
                expect(await evaluateIsExpanded(secondHeadingHandle)).toEqual(
                    false,
                );
                await page.keyboard.press('Space');
                expect(await evaluateIsExpanded(secondHeadingHandle)).toEqual(
                    true,
                );
            });

            it('When focus is on the accordion header for an expanded panel, collapses the panel if the implementation supports collapsing. Some implementations require one panel to be expanded at all times and allow only one panel to be expanded; so, they do not support a collapse function.', () => {
                // todo
            });
        });

        describe('Tab', () => {
            it('Moves focus to the next focusable element; all focusable elements in the accordion are included in the page Tab sequence.', async () => {
                const headingHandles = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                const firstHeadingHandle = headingHandles[0];
                const secondHeadingHandle = headingHandles[1];
                await firstHeadingHandle.focus();
                await page.keyboard.press('Tab');
                const secondIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    secondHeadingHandle,
                );
                expect(secondIsFocussed).toEqual(true);
            });
        });

        describe('Shift + Tab', () => {
            it('Moves focus to the previous focusable element; all focusable elements in the accordion are included in the page Tab sequence.', async () => {
                const headingHandles = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                const firstHeadingHandle = headingHandles[0];
                const secondHeadingHandle = headingHandles[1];
                await secondHeadingHandle.focus();
                await page.keyboard.down('Shift');
                await page.keyboard.press('Tab');
                await page.keyboard.up('Shift');
                const firstIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    firstHeadingHandle,
                );
                expect(firstIsFocussed).toEqual(true);
            });
        });

        describe('Down Arrow (Optional)', () => {
            it('If focus is on an accordion header, moves focus to the next accordion header. If focus is on the last accordion header, either does nothing or moves focus to the first accordion header.', () => {
                // todo
            });
        });

        describe('Up Arrow (Optional)', () => {
            it('If focus is on an accordion header, moves focus to the previous accordion header. If focus is on the first accordion header, either does nothing or moves focus to the last accordion header.', () => {
                // todo
            });
        });

        describe('Home (Optional)', () => {
            it('When focus is on an accordion header, moves focus to the first accordion header.', () => {
                // todo
            });
        });

        describe('End (Optional)', () => {
            it('When focus is on an accordion header, moves focus to the last accordion header.', () => {
                // todo
            });
        });
    });

    describe('WAI-ARIA Roles, States, and Properties', () => {
        it('The title of each accordion header is contained in an element with role button.', async () => {
            const roles = await page.evaluate(() => {
                const nodes = document
                    .querySelector('#classic-accordion')
                    .querySelectorAll('.accordion__heading');
                return Array.from(nodes).map(heading =>
                    heading.getAttribute('role'),
                );
            });
            expect(roles).toHaveLength(3);
            roles.forEach(role => expect(role).toBe('button'));
        });
<commit_msg>Add tests for optional keyboard functionality<commit_after>import path from 'path';
import { spawnSync } from 'child_process';

describe('WAI ARIA Spec', () => {
    beforeEach(async () => {
        await page.goto(`file:${path.resolve(__dirname, 'dist/index.html')}`);
    });

    describe('Canary tests', () => {
        it('Loads the Cypress Testing Sandbox', async () => {
            const title = await page.evaluate(() => document.title);
            expect(title).toBe(
                'React Accessible Accordion - Integration Test Sandbox',
            );
        });
        it('has rendered the "classic accordion" example', async () => {
            const qtyClassicAccordion = await page.evaluate(
                () => document.querySelectorAll('#classic-accordion').length,
            );
            expect(qtyClassicAccordion).toEqual(1);
        });
    });

    describe('Chrome Accessibility Tree', () => {
        it('matches snapshots', async () => {
            expect(await page.accessibility.snapshot()).toMatchSnapshot();
        });
    });

    describe('Keyboard Interaction', () => {
        describe('Enter or Space', () => {
            it('When focus is on the accordion header for a collapsed panel, expands the associated panel. If the implementation allows only one panel to be expanded, and if another panel is expanded, collapses that panel.', async () => {
                const headingHandles = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                expect(headingHandles.length).toEqual(3);

                const firstHeadingHandle = headingHandles[0];
                const secondHeadingHandle = headingHandles[1];

                function evaluateIsExpanded(headingHandle) {
                    return page
                        .evaluate(
                            heading => heading.getAttribute('aria-expanded'),
                            headingHandle,
                        )
                        .then(ariaExpanded => ariaExpanded === 'true');
                }

                // ENTER key
                await firstHeadingHandle.focus();
                expect(await evaluateIsExpanded(firstHeadingHandle)).toEqual(
                    false,
                );
                await page.keyboard.press('Enter');
                expect(await evaluateIsExpanded(firstHeadingHandle)).toEqual(
                    true,
                );

                // SPACE key
                await secondHeadingHandle.focus();
                expect(await evaluateIsExpanded(secondHeadingHandle)).toEqual(
                    false,
                );
                await page.keyboard.press('Space');
                expect(await evaluateIsExpanded(secondHeadingHandle)).toEqual(
                    true,
                );
            });

            it('When focus is on the accordion header for an expanded panel, collapses the panel if the implementation supports collapsing. Some implementations require one panel to be expanded at all times and allow only one panel to be expanded; so, they do not support a collapse function.', () => {
                // todo
            });
        });

        describe('Tab', () => {
            it('Moves focus to the next focusable element; all focusable elements in the accordion are included in the page Tab sequence.', async () => {
                const [firstHeadingHandle, secondHeadingHandle] = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                await firstHeadingHandle.focus();
                await page.keyboard.press('Tab');
                const secondIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    secondHeadingHandle,
                );
                expect(secondIsFocussed).toEqual(true);
            });
        });

        describe('Shift + Tab', () => {
            it('Moves focus to the previous focusable element; all focusable elements in the accordion are included in the page Tab sequence.', async () => {
                const [firstHeadingHandle, secondHeadingHandle] = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                await secondHeadingHandle.focus();
                await page.keyboard.down('Shift');
                await page.keyboard.press('Tab');
                await page.keyboard.up('Shift');
                const firstIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    firstHeadingHandle,
                );
                expect(firstIsFocussed).toEqual(true);
            });
        });

        describe('Down Arrow (Optional)', () => {
            xit('If focus is on an accordion header, moves focus to the next accordion header.', async () => {
                const [firstHeadingHandle, secondHeadingHandle] = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                await firstHeadingHandle.focus();
                await page.keyboard.press('ArrowDown');
                const secondIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    secondHeadingHandle,
                );
                expect(secondIsFocussed).toEqual(true);
            });

            xit('If focus is on the last accordion header, either does nothing or moves focus to the first accordion header.', () => {
                // todo
            });
        });

        describe('Up Arrow (Optional)', () => {
            xit('If focus is on an accordion header, moves focus to the previous accordion header.', () => {
                const [firstHeadingHandle, secondHeadingHandle] = await page.$$(
                    '#classic-accordion .accordion__heading',
                );
                await secondHeadingHandle.focus();
                await page.keyboard.press('ArrowUp');
                const firstIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    firstHeadingHandle,
                );
                expect(firstIsFocussed).toEqual(true);
            });

            xit('If focus is on the first accordion header, either does nothing or moves focus to the last accordion header.', () => {
                // todo
            });
        });

        describe('Home (Optional)', () => {
            xit('When focus is on an accordion header, moves focus to the first accordion header.', () => {
                const [
                    firstHeadingHandle,
                    secondHeadingHandle,
                    thirdHeadingHandle,
                ] = await page.$$('#classic-accordion .accordion__heading');
                await thirdHeadingHandle.focus();
                await page.keyboard.press('Home');
                const firstIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    firstHeadingHandle,
                );
                expect(firstIsFocussed).toEqual(true);
            });
        });

        describe('End (Optional)', () => {
            xit('When focus is on an accordion header, moves focus to the last accordion header.', () => {
                const [
                    firstHeadingHandle,
                    secondHeadingHandle,
                    thirdHeadingHandle,
                ] = await page.$$('#classic-accordion .accordion__heading');
                await firstHeadingHandle.focus();
                await page.keyboard.press('End');
                const thirdIsFocussed = await page.evaluate(
                    heading => document.activeElement === heading,
                    thirdHeadingHandle,
                );
                expect(thirdIsFocussed).toEqual(true);
            });
        });
    });

    describe('WAI-ARIA Roles, States, and Properties', () => {
        it('The title of each accordion header is contained in an element with role button.', async () => {
            const roles = await page.evaluate(() => {
                const nodes = document
                    .querySelector('#classic-accordion')
                    .querySelectorAll('.accordion__heading');
                return Array.from(nodes).map(heading =>
                    heading.getAttribute('role'),
                );
            });
            expect(roles).toHaveLength(3);
            roles.forEach(role => expect(role).toBe('button'));
        });

{'fraction_non_alphanumeric': 0.10690219169120052, 'fraction_numerical': 0.0009159306509649984, 'mean_word_length': 1.6215057451552048, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '491260', 'n_tokens_mistral': 3635, 'n_tokens_neox': 3428, 'n_words': 940}