diff --git a/.reuse/dep5 b/.reuse/dep5 index 6f07db4c71..e3341e2b8e 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -7,7 +7,7 @@ Files: package.json package-lock.json .github/pull_request_template.md Copyright: Nextcloud GmbH and Nextcloud contributors License: AGPL-3.0-or-later -Files: styleguide/assets/icons.css styleguide/assets/server.css cypress/snapshots/* tests/unit/functions/usernameToColor/__snapshots__/usernameToColor.spec.js.snap +Files: styleguide/assets/icons.css cypress/snapshots/* tests/unit/functions/usernameToColor/__snapshots__/usernameToColor.spec.js.snap Copyright: Nextcloud GmbH and Nextcloud contributors License: AGPL-3.0-or-later diff --git a/cypress/commands.d.ts b/cypress/commands.d.ts new file mode 100644 index 0000000000..c54b92419b --- /dev/null +++ b/cypress/commands.d.ts @@ -0,0 +1,19 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { mount } from '@cypress/vue2' + +// Augment the Cypress namespace to include type definitions for +// your custom commands +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + interface Chainable { + mount: typeof mount + } + } +} + +export {} diff --git a/cypress/component/NcCheckboxRadioSwitch.cy.ts b/cypress/component/NcCheckboxRadioSwitch.cy.ts new file mode 100644 index 0000000000..81dc6d3103 --- /dev/null +++ b/cypress/component/NcCheckboxRadioSwitch.cy.ts @@ -0,0 +1,32 @@ +/** + * SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import NcCheckboxRadioSwitch from '../../src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue' + +describe('NcCheckboxRadioSwitch', () => { + it('Sets attributes correctly', () => { + cy.mount({ + render: (h) => h(NcCheckboxRadioSwitch, { + // TODO: With Vue3 move class and style to attrs + class: 'my-class', + style: 'background: red;', + attrs: { + 'aria-describedby': 'unique-id', + 'data-my-attribute': 'yes', + }, + }, ['My checkbox']), + }).then(({ wrapper }) => { + // Class and style belong the wrapper + expect(wrapper.classes('my-class')).to.be.true + // expect(wrapper.attributes('style')).to.equal('background: red;') + // Custom data attributes too + expect(wrapper.attributes('data-my-attribute')).to.equal('yes') + // real HTML attributes are passed to the real checkbox + expect(wrapper.attributes('aria-describedby')).to.be.undefined + }) + + cy.findByRole('checkbox').should('have.attr', 'aria-describedby', 'unique-id') + }) +}) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 729eb70cef..59e5c1ad00 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -3,8 +3,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +import { mount } from '@cypress/vue2' import { addCompareSnapshotCommand } from 'cypress-visual-regression/dist/command' import '@testing-library/cypress/add-commands' addCompareSnapshotCommand() + +// Example use: +// cy.mount(MyComponent) +Cypress.Commands.add('mount', mount) diff --git a/cypress/support/component.ts b/cypress/support/component.ts index 233949481a..b2224d3df7 100644 --- a/cypress/support/component.ts +++ b/cypress/support/component.ts @@ -10,22 +10,3 @@ import '../../styleguide/assets/icons.css' // cypress commands import './commands' -import { mount } from '@cypress/vue2' - -// Augment the Cypress namespace to include type definitions for -// your custom command. -// Alternatively, can be defined in cypress/support/component.d.ts -// with a at the top of your spec. - -declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - interface Chainable { - mount: typeof mount - } - } -} - -// Example use: -// cy.mount(MyComponent) -Cypress.Commands.add('mount', mount) diff --git a/src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue b/src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue index d6077abff7..d4e534d5a3 100644 --- a/src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue +++ b/src/components/NcCheckboxRadioSwitch/NcCheckboxRadioSwitch.vue @@ -258,7 +258,7 @@ export default { class="checkbox-radio-switch" :style="cssVars" :type="isButtonType ? 'button' : null" - v-bind="isButtonType ? $attrs : {}" + v-bind="isButtonType ? $attrs : dataAttrs" v-on="isButtonType ? listeners : null"> key.startsWith('data-'))) + }, + + nonDataAttrs() { + // filter all non-data attributes + return Object.fromEntries(Object.entries(this.$attrs) + .filter(([key]) => !key.startsWith('data-'))) + }, + isButtonType() { return this.type === TYPE_BUTTON }, diff --git a/tests/unit/components/NcCheckboxRadioSwitch/checkbox.spec.js b/tests/unit/components/NcCheckboxRadioSwitch/checkbox.spec.js index f58d4e7939..c5eef03e65 100644 --- a/tests/unit/components/NcCheckboxRadioSwitch/checkbox.spec.js +++ b/tests/unit/components/NcCheckboxRadioSwitch/checkbox.spec.js @@ -17,7 +17,7 @@ describe('NcCheckboxRadioSwitch', () => { expect(wrapper.text()).toContain('Test') }) - it('forwards aria-invalid and aria-errormessage to input', () => { + it('forwards all but data- attributes to the input', () => { const wrapper = shallowMount(NcCheckboxRadioSwitch, { slots: { default: 'Test', @@ -25,11 +25,17 @@ describe('NcCheckboxRadioSwitch', () => { attrs: { 'aria-invalid': 'true', 'aria-errormessage': 'id-test', + 'data-test': 'checkbox-test-data-attr', + title: 'Test title', }, }) const input = wrapper.find('input') expect(input.attributes('aria-invalid')).toBe('true') expect(input.attributes('aria-errormessage')).toBe('id-test') + expect(input.attributes('title')).toBe('Test title') + expect(input.attributes('data-test')).not.toBe('checkbox-test-data-attr') + expect(wrapper.attributes('data-test')).toBe('checkbox-test-data-attr') + expect(wrapper.attributes('title')).not.toBe('Test title') }) })