From 9113322b70556e4626e308134b1f517472f3fcaf Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Mon, 24 Jul 2023 15:02:47 +0200 Subject: [PATCH] feat(clipboard): add test --- .../clipboard/ods-clipboard-attributes.ts | 11 +++- .../clipboard/ods-clipboard-controller.ts | 13 +--- .../ods-clipboard-default-attributes.ts | 6 +- .../clipboard/ods-clipboard-events.ts | 2 +- .../src/utils/clipboard/write-on-clipboard.ts | 4 ++ .../clipboard/specifications-clipboard.mdx | 4 +- .../osds-clipboard.e2e.screenshot.ts | 29 ++++++++- .../osds-clipboard/osds-clipboard.e2e.ts | 36 +++++++++-- .../osds-clipboard/osds-clipboard.scss | 21 ------- .../osds-clipboard/osds-clipboard.spec.ts | 60 +++++++++++++++---- .../osds-clipboard/osds-clipboard.tsx | 39 ++++++++---- .../styles/osds-clipboard.color.scss | 27 --------- .../styles/osds-clipboard.mixins.scss | 13 ---- .../styles/osds-clipboard.size.scss | 7 --- .../styles/osds-clipboard.typography.scss | 16 ----- .../components/clipboard/src/global.dev.ts | 2 + .../components/clipboard/src/global.test.ts | 3 + .../components/clipboard/src/index.html | 9 ++- .../components/clipboard/stencil.config.ts | 4 +- .../clipboard.web-components.stories.ts | 13 +++- 20 files changed, 185 insertions(+), 134 deletions(-) create mode 100644 packages/libraries/core/src/utils/clipboard/write-on-clipboard.ts delete mode 100644 packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.color.scss delete mode 100644 packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.mixins.scss delete mode 100644 packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.size.scss delete mode 100644 packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.typography.scss create mode 100644 packages/stencil/components/clipboard/src/global.test.ts diff --git a/packages/libraries/core/src/components/clipboard/ods-clipboard-attributes.ts b/packages/libraries/core/src/components/clipboard/ods-clipboard-attributes.ts index cee94798a5..2b2a6a526d 100644 --- a/packages/libraries/core/src/components/clipboard/ods-clipboard-attributes.ts +++ b/packages/libraries/core/src/components/clipboard/ods-clipboard-attributes.ts @@ -1,7 +1,12 @@ import { OdsComponentAttributes } from '../ods-component-attributes'; export interface OdsClipboardAttributes extends OdsComponentAttributes { - /** - * Clipboard attribute description - */ + /** Indicates if the input is full width or not: see component principles */ + flex?: boolean; + + /** Input text value */ + value: string; + + /** Disabled the input, the focus, and the tooltip */ + disabled?: boolean; } diff --git a/packages/libraries/core/src/components/clipboard/ods-clipboard-controller.ts b/packages/libraries/core/src/components/clipboard/ods-clipboard-controller.ts index 82a57b59fa..e494bc5596 100644 --- a/packages/libraries/core/src/components/clipboard/ods-clipboard-controller.ts +++ b/packages/libraries/core/src/components/clipboard/ods-clipboard-controller.ts @@ -1,21 +1,14 @@ import { OdsClipboard } from './ods-clipboard'; import { OdsComponentController } from '../ods-component-controller'; +import { writeOnClipboard } from '../../utils/clipboard/write-on-clipboard'; -/** - * common controller logic for cmpnt component used by the different implementations. - * it contains all the glue between framework implementation and the third party service. - */ export class OdsClipboardController extends OdsComponentController { - // private readonly logger = new OdsLogger('OdsClipboardController'); constructor(component: OdsClipboard) { super(component); } - /** - * Attributes validation documentation - */ - validateAttributes(): void { - return; + async handlerClick(value: string): Promise { + await writeOnClipboard(value); } } diff --git a/packages/libraries/core/src/components/clipboard/ods-clipboard-default-attributes.ts b/packages/libraries/core/src/components/clipboard/ods-clipboard-default-attributes.ts index b9f0aecbf9..685b78d93d 100644 --- a/packages/libraries/core/src/components/clipboard/ods-clipboard-default-attributes.ts +++ b/packages/libraries/core/src/components/clipboard/ods-clipboard-default-attributes.ts @@ -1,7 +1,9 @@ import { OdsClipboardAttributes } from './ods-clipboard-attributes'; -export const odsClipboardDefaultAttributesDoc = { - // default attributes +export const odsClipboardDefaultAttributesDoc = { + flex: false, + value: '', + disabled: false, } as const; export const odsClipboardDefaultAttributes = odsClipboardDefaultAttributesDoc as OdsClipboardAttributes; diff --git a/packages/libraries/core/src/components/clipboard/ods-clipboard-events.ts b/packages/libraries/core/src/components/clipboard/ods-clipboard-events.ts index 9fb4d8f4ec..7efeb28f7c 100644 --- a/packages/libraries/core/src/components/clipboard/ods-clipboard-events.ts +++ b/packages/libraries/core/src/components/clipboard/ods-clipboard-events.ts @@ -1,5 +1,5 @@ import { OdsComponentEvents } from '../ods-component-events'; export interface OdsClipboardEvents extends OdsComponentEvents { - // Events + odsClipboardCopied: string; } diff --git a/packages/libraries/core/src/utils/clipboard/write-on-clipboard.ts b/packages/libraries/core/src/utils/clipboard/write-on-clipboard.ts new file mode 100644 index 0000000000..ff71991c37 --- /dev/null +++ b/packages/libraries/core/src/utils/clipboard/write-on-clipboard.ts @@ -0,0 +1,4 @@ +export function writeOnClipboard(textToWrite: string): Promise { + console.log('test', textToWrite); + return navigator.clipboard.writeText(textToWrite); +} \ No newline at end of file diff --git a/packages/specifications/components/clipboard/specifications-clipboard.mdx b/packages/specifications/components/clipboard/specifications-clipboard.mdx index fd752aa064..2979d81158 100644 --- a/packages/specifications/components/clipboard/specifications-clipboard.mdx +++ b/packages/specifications/components/clipboard/specifications-clipboard.mdx @@ -1,10 +1,10 @@ import {Description} from '@storybook/addon-docs'; -[//]: # (import Specs from '@ovhcloud/ods-core/src/components/clipboard/docs/spec.md';) +import Specs from '@ovhcloud/ods-core/src/components/clipboard/docs/spec.md'; import SpecsClipboardContents from './specifications-clipboard-contents.mdx'; import SpecsClipboardTests from './specifications-clipboard-tests.mdx'; -[//]: # ({Specs}) +{Specs} ## Contents diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.screenshot.ts b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.screenshot.ts index 4ecdd6a6af..b657f57a25 100644 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.screenshot.ts +++ b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.screenshot.ts @@ -4,14 +4,14 @@ import { OdsComponentAttributes2StringAttributes, odsClipboardDefaultAttributes, } from '@ovhcloud/ods-core'; -import { OdsCreateAttributes, OdsStringAttributes2Str, odsClipboardBaseAttributes } from '@ovhcloud/ods-testing'; +import { OdsCreateAttributes, OdsStringAttributes2Str } from '@ovhcloud/ods-testing'; describe('e2e:osds-clipboard', () => { let page: E2EPage; let el: E2EElement; async function setup({ attributes = {}, html = `` }: { attributes?: Partial, html?: string } = {}) { - const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardBaseAttributes); + const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardDefaultAttributes); const stringAttributes = OdsComponentAttributes2StringAttributes(minimalAttributes, odsClipboardDefaultAttributes); page = await newE2EPage(); @@ -25,6 +25,29 @@ describe('e2e:osds-clipboard', () => { } describe('screenshots', () => { - // Screenshot testing + [false, true].forEach((flex) => { + [false, true].forEach((disabled) => { + [undefined, 'value'].forEach((value) => { + it([flex, disabled, value].join(', '), async () => { + await setup({ + attributes: { + flex, + disabled, + value + }, + }); + await page.waitForChanges(); + + await page.evaluate(() => { + const element = document.querySelector('osds-clipboard') as HTMLElement; + return { width: element.clientWidth, height: element.clientHeight }; + }); + await page.setViewport({ width: 600, height: 600 }); + const results = await page.compareScreenshot('clipboard', { fullPage: false, omitBackground: true }); + expect(results).toMatchScreenshot({ allowableMismatchedRatio: 0 }) + }); + }); + }); + }); }); }); diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.ts b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.ts index d746d1fbe0..666d55f1ae 100644 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.ts +++ b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.e2e.ts @@ -1,20 +1,27 @@ import { E2EElement, E2EPage, newE2EPage } from '@stencil/core/testing'; import { OdsClipboardAttributes, OdsComponentAttributes2StringAttributes, odsClipboardDefaultAttributes } from '@ovhcloud/ods-core'; -import { OdsCreateAttributes, OdsStringAttributes2Str, odsClipboardBaseAttributes } from '@ovhcloud/ods-testing'; +import { OdsCreateAttributes, OdsStringAttributes2Str } from '@ovhcloud/ods-testing'; describe('e2e:osds-clipboard', () => { let page: E2EPage; let el: E2EElement; + let input: E2EElement; async function setup({ attributes }: { attributes: Partial }) { - const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardBaseAttributes); + const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardDefaultAttributes); const stringAttributes = OdsComponentAttributes2StringAttributes(minimalAttributes, odsClipboardDefaultAttributes); page = await newE2EPage(); + const origin = await page.evaluate(() => window.origin); + + const browserContext = page.browserContext(); + await browserContext.overridePermissions(origin, ['clipboard-write', 'clipboard-read']); await page.setContent(``); await page.evaluate(() => document.body.style.setProperty('margin', '0px')); - + el = await page.find('osds-clipboard'); + input = await page.find('osds-clipboard >>> osds-input'); + await page.waitForChanges(); } it('should render', async () => { @@ -22,7 +29,28 @@ describe('e2e:osds-clipboard', () => { expect(el).not.toBeNull(); expect(el).toHaveClass('hydrated'); - // E2E testing + expect(input).not.toBeNull(); + expect(input).toHaveClass('hydrated'); }); + it.only('should copy the input value', async () => { + const value = 'text to copy'; + + await setup({ attributes: { value } }); + + await input.click(); + + expect(await page.evaluate(() => navigator.clipboard.readText())).toBe(value); + }); + + // it('should not copy the input value because of disabled', async () => { + // const value = 'text to copy'; + // await setup({ attributes: { value, disabled: true } }); + // await page.evaluate(() => navigator.clipboard.writeText('')); + + // await input.click(); + + // expect(await page.evaluate(() => navigator.clipboard.readText())).toBe(''); + // }); + }); diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.scss b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.scss index 7b87b4fd59..73b7ccecea 100644 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.scss +++ b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.scss @@ -1,24 +1,3 @@ -@import 'styles/osds-clipboard.mixins'; -@import 'styles/osds-clipboard.color'; -@import 'styles/osds-clipboard.size'; -@import 'styles/osds-clipboard.typography'; @import '~@ovhcloud/ods-theming/color/ods-theming-color'; @import '~@ovhcloud/ods-theming/ods-theme'; -// CSS targeted only for this component -// /!\ for theming purposes, it has to be done in theming files -// (i.e. packages/libraries/theming/...) -:host { - -} - -:host([attribute]) { - -} - -// apply the theme template for the component -@include ods-theme-component() { - @include osds-clipboard-theme-color(); - @include osds-clipboard-theme-size(); - @include osds-clipboard-theme-typography(); -} diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.spec.ts b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.spec.ts index 9470c9a34a..ba452fd973 100644 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.spec.ts +++ b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.spec.ts @@ -9,12 +9,9 @@ import { import { OdsCreateAttributes, OdsStringAttributes2Str, - odsClipboardBaseAttributes, odsUnitTestAttribute } from '@ovhcloud/ods-testing'; import { SpecPage, newSpecPage } from '@stencil/core/testing'; - -import { OdsThemeColorIntentList } from '@ovhcloud/ods-theming'; import { OsdsClipboard } from './osds-clipboard'; import { getAttributeContextOptions } from '@ovhcloud/ods-stencil/libraries/stencil-testing'; @@ -23,13 +20,14 @@ describe('spec:osds-clipboard', () => { let root: HTMLElement | undefined; let instance: OsdsClipboard; let controller: OdsClipboardController; + let input: HTMLElement; afterEach(() => { jest.clearAllMocks(); }); async function setup({ attributes = {} }: { attributes?: Partial } = {}) { - const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardBaseAttributes); + const minimalAttributes: OdsClipboardAttributes = OdsCreateAttributes(attributes, odsClipboardDefaultAttributes); const stringAttributes = OdsComponentAttributes2StringAttributes(minimalAttributes, odsClipboardDefaultAttributes); page = await newSpecPage({ @@ -40,6 +38,7 @@ describe('spec:osds-clipboard', () => { root = page.root; instance = page.rootInstance; controller = (OdsClipboardController as unknown as jest.SpyInstance).mock.instances[0]; + input = root.shadowRoot.querySelector('osds-input'); } it('should render', async () => { @@ -55,14 +54,55 @@ describe('spec:osds-clipboard', () => { setup }; - // Attributes Unit testing + describe('flex', () => { + odsUnitTestAttribute({ + ...getAttributeContextOptions({ + name: 'flex', + list: [true, false], + defaultValue: odsClipboardDefaultAttributes.flex, + ...config + }) + }); + }); + + describe('disabled', () => { + odsUnitTestAttribute({ + ...getAttributeContextOptions({ + name: 'disabled', + list: [true, false], + defaultValue: odsClipboardDefaultAttributes.disabled, + ...config + }) + }); + }); + + describe('value', () => { + odsUnitTestAttribute({ + ...getAttributeContextOptions({ + name: 'value', + list: ['', 'new value'], + defaultValue: odsClipboardDefaultAttributes.value, + ...config + }) + }); + }); }); - describe('controller', () => { - it('should call controller.validateAttributes', async () => { - await setup(); - expect(controller.validateAttributes).toHaveBeenCalledWith(); - expect(controller.validateAttributes).toHaveBeenCalledTimes(1); + describe('methods', () => { + it('should call handlerClick controller', async () => { + await setup({}); + instance.handlerClick(); + input.click(); + + expect(controller.handlerClick).toHaveBeenCalledTimes(2); }); + + it('should not call handlerClick controller because of disabled', async () => { + await setup({ attributes: { disabled: true } }); + instance.handlerClick(); + input.click(); + + expect(controller.handlerClick).not.toHaveBeenCalled(); + }) }); }); diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.tsx b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.tsx index 3e56d2ab08..a41417c6c4 100644 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.tsx +++ b/packages/stencil/components/clipboard/src/components/osds-clipboard/osds-clipboard.tsx @@ -1,12 +1,16 @@ -import { Component, Element, Host, h } from '@stencil/core'; +import { Component, Element, Host, h, Prop, Event, EventEmitter } from '@stencil/core'; import { OdsClipboard, OdsClipboardController, + odsClipboardDefaultAttributes, OdsClipboardEvents, OdsClipboardMethods, + OdsIconName, + OdsInputType, // odsClipboardDefaultAttributes } from '@ovhcloud/ods-core'; import { OdsStencilEvents, OdsStencilMethods } from '@ovhcloud/ods-stencil/libraries/stencil-core'; +import { OdsThemeColorIntent } from '@ovhcloud/ods-theming'; /** * @slot (unnamed) - Clipboard content @@ -20,18 +24,23 @@ export class OsdsClipboard implements OdsClipboard; + handlerClick(): void { + if (this.disabled) { + return; + } + this.controller.handlerClick(this.value); } render() { @@ -39,7 +48,15 @@ export class OsdsClipboard implements OdsClipboard - {/* UI template */} + this.handlerClick() }> + ); diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.color.scss b/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.color.scss deleted file mode 100644 index 0cba877e04..0000000000 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.color.scss +++ /dev/null @@ -1,27 +0,0 @@ -@import '~@ovhcloud/ods-theming/color/ods-component-color'; -@import './osds-clipboard.mixins'; - -@mixin osds-clipboard-theme-color-variant-default() { - @include ods-and-all-hue-foreach-theme-color(( - color: '800', - background-color: '100' - )) using($colors) { - @include osds-clipboard-on-selected-host() { - //color: map_get($colors, color); - //background-color: map_get($colors, background-color); - } - } -} - -// Main CSS color theme mixin -@mixin osds-clipboard-theme-color() { - /** base colors */ - :host { - border-color: transparent; - } - - /** no variant specified: default variant colors */ - :not([variant]) { - @include osds-clipboard-theme-color-variant-default(); - } -} diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.mixins.scss b/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.mixins.scss deleted file mode 100644 index 1cf43bd352..0000000000 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.mixins.scss +++ /dev/null @@ -1,13 +0,0 @@ -// general mixins and functions for the component - -@mixin osds-clipboard-on-selected-host() { - :host(&) { - @content; - } -} - -@mixin osds-clipboard-on-main-element() { - .clipboard__wrapper { - @content; - } -} diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.size.scss b/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.size.scss deleted file mode 100644 index e3865d79ac..0000000000 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.size.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import './osds-clipboard.mixins'; -@import '~@ovhcloud/ods-theming/size/ods-component-size'; - -// Main CSS mixin for sizes -@mixin osds-clipboard-theme-size() { - -} diff --git a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.typography.scss b/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.typography.scss deleted file mode 100644 index d0b74a9481..0000000000 --- a/packages/stencil/components/clipboard/src/components/osds-clipboard/styles/osds-clipboard.typography.scss +++ /dev/null @@ -1,16 +0,0 @@ -@import '~@ovhcloud/ods-theming/typography/ods-theming-typography'; -@import '~@ovhcloud/ods-theming/typography/ods-component-typography'; -@import './osds-clipboard.mixins'; - -// Main CSS mixin for typography -@mixin osds-clipboard-theme-typography() { - :host([size='md']) .clipboard__wrapper { - //$typography-properties: ods-get-typography-properties(body, '400'); - //font-family: ods-get-typography-property($typography-properties, font-family); - //font-size: ods-get-typography-property($typography-properties, font-size); - //font-style: ods-get-typography-property($typography-properties, font-style); - //font-weight: ods-get-typography-property($typography-properties, font-weight); - //letter-spacing: ods-get-typography-property($typography-properties, letter-spacing); - //line-height: ods-get-typography-property($typography-properties, line-height); - } -} diff --git a/packages/stencil/components/clipboard/src/global.dev.ts b/packages/stencil/components/clipboard/src/global.dev.ts index 3d6ce693ca..911907ccb5 100644 --- a/packages/stencil/components/clipboard/src/global.dev.ts +++ b/packages/stencil/components/clipboard/src/global.dev.ts @@ -7,6 +7,8 @@ import './components'; import './global'; import { OdsLogger } from '@ovhcloud/ods-core'; +import '@ovhcloud/ods-stencil/components/input'; + const logger = new OdsLogger('global-dev'); logger.log('init'); diff --git a/packages/stencil/components/clipboard/src/global.test.ts b/packages/stencil/components/clipboard/src/global.test.ts new file mode 100644 index 0000000000..b2c136c43a --- /dev/null +++ b/packages/stencil/components/clipboard/src/global.test.ts @@ -0,0 +1,3 @@ +import './global'; + +import '@ovhcloud/ods-stencil/components/input'; diff --git a/packages/stencil/components/clipboard/src/index.html b/packages/stencil/components/clipboard/src/index.html index 36a81c5267..1cfc9f6f29 100644 --- a/packages/stencil/components/clipboard/src/index.html +++ b/packages/stencil/components/clipboard/src/index.html @@ -15,7 +15,14 @@ -Clipboard +

Clipboard

+Clipboard + +

Clipboard flex

+Clipboard + +

Clipboard disabled

+Clipboard