Skip to content

Commit

Permalink
fix e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
alizedebray committed Jul 3, 2024
1 parent 6b8095d commit fb37469
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 51 deletions.
72 changes: 45 additions & 27 deletions packages/components/cypress/e2e/collapsible.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,75 @@ const COLLAPSIBLE_ID = '6a91848c-16ec-4a23-bc45-51c797b5b2c3';
describe('collapsible', () => {
describe('default', () => {
beforeEach(() => {
cy.getComponent('collapsible', COLLAPSIBLE_ID);
cy.get('@collapsible').find('.collapse').as('collapse');
cy.get(`#button--${COLLAPSIBLE_ID}--default`).as('toggler');
cy.getComponents(COLLAPSIBLE_ID, 'default', 'post-collapsible', 'post-collapsible-trigger');
cy.get('@collapsible-trigger').find('.btn').as('trigger');
});

it('should render', () => {
it('should have a collapsible', () => {
cy.get('@collapsible').should('exist');
});

it('should have a collapse', () => {
cy.get('@collapse').should('exist');
it('should have a trigger', () => {
cy.get('@trigger').should('exist');
});

it('should have a toggle button', () => {
cy.get('@toggler').should('exist');
it('should show the collapsible', () => {
cy.get('@collapsible').should(`be.visible`);
});

it('should be expanded', () => {
cy.get('@collapse').should(`be.visible`);
it('should set the correct ARIA attribute on the trigger', () => {
cy.get('@collapsible')
.invoke('attr', 'id')
.then(collapsibleId => {
cy.get('@trigger').should('have.attr', 'aria-controls', collapsibleId);
});
cy.get('@trigger').should('have.attr', 'aria-expanded', 'true');
});

it('should be collapsed after clicking on the toggle button once', () => {
cy.get('@toggler').click();
cy.get('@collapse').should(`be.hidden`);
it('should hide the collapsible after clicking on the trigger once', () => {
cy.get('@trigger').click();
cy.get('@collapsible').should(`be.hidden`);
});

it('should be expanded after clicking on the toggle button twice', () => {
cy.get('@toggler').dblclick();
cy.get('@collapse').should(`be.visible`);
it('should update the "aria-expanded" attribute after hiding the collapsible', () => {
cy.get('@trigger').click();
cy.get('@trigger').should('have.attr', 'aria-expanded', 'false');
});

it('should show the collapsible after clicking on the trigger twice', () => {
cy.get('@trigger').dblclick();
cy.get('@collapsible').should(`be.visible`);
});

it('should update the "aria-expanded" attribute after showing the collapsible', () => {
cy.get('@trigger').click();
cy.get('@trigger').should('have.attr', 'aria-expanded', 'true');
});
});

describe('initially collapsed', () => {
beforeEach(() => {
cy.getComponent('collapsible', COLLAPSIBLE_ID, 'initially-collapsed');
cy.get('@collapsible').find('.collapse').as('collapse');
cy.get(`#button--${COLLAPSIBLE_ID}--initially-collapsed`).as('toggler');
cy.getComponents(
COLLAPSIBLE_ID,
'initially-collapsed',
'post-collapsible',
'post-collapsible-trigger',
);
cy.get('@collapsible-trigger').find('.btn').as('trigger');
});

it('should be collapsed', () => {
cy.get('@collapse').should(`be.hidden`);
it('should hide the collapsible', () => {
cy.get('@collapsible').should(`be.hidden`);
});

it('should be expanded after clicking on the toggle button once', () => {
cy.get('@toggler').click();
cy.get('@collapse').should(`be.visible`);
it('should show the collapsible after clicking on the trigger once', () => {
cy.get('@trigger').click();
cy.get('@collapsible').should(`be.visible`);
});

it('should be collapsed after clicking on the toggle button twice', () => {
cy.get('@toggler').dblclick();
cy.get('@collapse').should(`be.hidden`);
it('should hide the collapsible after clicking on the trigger twice', () => {
cy.get('@trigger').dblclick();
cy.get('@collapsible').should(`be.hidden`);
});
});
});
Expand Down
10 changes: 8 additions & 2 deletions packages/components/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,16 @@ export const isInViewport = function (_chai: Chai.ChaiStatic) {
chai.use(isInViewport);

Cypress.Commands.add('getComponent', (component: string, id: string, story = 'default') => {
cy.getComponents(id, story, component);
});

Cypress.Commands.add('getComponents', (id: string, story: string, ...components: string[]) => {
cy.visit(`/iframe.html?id=${id}--${story}`);

const alias = component.replace(/^post-/, '');
cy.get(`post-${alias}`, { timeout: 30000 }).as(alias);
components.forEach(component => {
const alias = component.replace(/^post-/, '');
cy.get(`post-${alias}.hydrated`, { timeout: 30000 }).as(alias);
});

cy.injectAxe();
});
Expand Down
1 change: 1 addition & 0 deletions packages/components/cypress/support/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ declare global {
namespace Cypress {
interface Chainable {
getComponent(component: string, id: string, story?: string): Chainable<any>;
getComponents(id: string, story: string, ...component: string[]): Chainable<any>;
getSnapshots(component: string): Chainable<any>;
checkAriaExpanded(
controlledElementSelector: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ export class PostCollapsibleTrigger {
@Prop() for: string;

@Watch('for')
setAriaControls() {
setAriaAttributes() {
checkNonEmpty(this.for, 'The post-collapsible-trigger "for" prop is required.');
checkType(this.for, 'string', 'The post-collapsible-trigger "for" prop should be a id.');

// Add collapsible id to aria-controls
if (this.trigger) this.trigger.setAttribute('aria-controls', this.for);
if (this.trigger) {
this.trigger.setAttribute('aria-controls', this.for);

const isOpen = !this.collapsible?.collapsed;
if (isOpen !== undefined) this.trigger.setAttribute('aria-expanded', `${isOpen}`);
}
}

componentDidLoad() {
connectedCallback() {
const firstChild = this.host.children[0];
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE) {
this.trigger = firstChild as HTMLElement;
Expand All @@ -43,7 +48,7 @@ export class PostCollapsibleTrigger {
this.trigger.setAttribute('role', 'button');
}

this.setAriaControls();
this.setAriaAttributes();
}

@Listen('pointerdown')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
:host {
display: block;
}

.collapse {
overflow: hidden;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Host,
Method,
Prop,
State,
Watch,
} from '@stencil/core';
import { version } from '@root/package.json';
Expand All @@ -26,12 +25,9 @@ import { checkEmptyOrType, isMotionReduced } from '@/utils';
export class PostCollapsible {
private isLoaded = false;
private isOpen = true;
private collapsible: HTMLElement;

@Element() host: HTMLPostCollapsibleElement;

@State() id: string;

/**
* If `true`, the element is initially collapsed otherwise it is displayed.
*/
Expand All @@ -57,10 +53,6 @@ export class PostCollapsible {
this.validateCollapsed();
}

componentWillRender() {
this.id = this.host.id || `c${crypto.randomUUID()}`;
}

componentDidLoad() {
if (this.collapsed) void this.toggle(false);
this.isLoaded = true;
Expand All @@ -78,7 +70,7 @@ export class PostCollapsible {
this.isOpen = !this.isOpen;
if (this.isLoaded) this.postToggle.emit(this.isOpen);

const animation = open ? expand(this.collapsible) : collapse(this.collapsible);
const animation = open ? expand(this.host) : collapse(this.host);

if (!this.isLoaded || isMotionReduced()) animation.finish();

Expand All @@ -91,10 +83,8 @@ export class PostCollapsible {

render() {
return (
<Host id={this.id} data-version={version}>
<div class="collapse" id={`${this.id}--collapse`} ref={el => (this.collapsible = el)}>
<slot />
</div>
<Host data-version={version}>
<slot />
</Host>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ const { id, ...metaWithoutId } = meta;

export default {
...metaWithoutId,
decorators: [],
title: 'Snapshots',
};

type Story = StoryObj<HTMLPostCollapsibleElement>;

export const Collapsible: Story = {
render: (_args: Args, context: StoryContext<HTMLPostCollapsibleElement>) => {
let index = 0;

const templateVariants = bombArgs({
collapsed: [false, true],
}).map((args: Args) => {
return html`
<div class="col-6 p-3">
<p>collapsed: ${args.collapsed}</p>
${meta.render?.({ ...context.args, ...Default.args, ...args }, context)}
${meta.render?.(
{ ...context.args, ...Default.args, ...args },
{ ...context, id: `${context.id}-${index++}` },
)}
</div>
`;
});
Expand Down

0 comments on commit fb37469

Please sign in to comment.