diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index e9ed43e81780b..5b22e9aa79658 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -24,20 +24,20 @@ export function createJestConfig({ kibanaDirectory, xPackKibanaDirectory }) { '^plugins/([^/.]*)(.*)': `${kibanaDirectory}/src/legacy/core_plugins/$1/public$2`, '^legacy/plugins/xpack_main/(.*);': `${xPackKibanaDirectory}/legacy/plugins/xpack_main/public/$1`, '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': fileMockPath, + '\\.module.(css|scss)$': 'identity-obj-proxy', '\\.(css|less|scss)$': `${kibanaDirectory}/src/dev/jest/mocks/style_mock.js`, '^test_utils/enzyme_helpers': `${xPackKibanaDirectory}/test_utils/enzyme_helpers.tsx`, '^test_utils/find_test_subject': `${xPackKibanaDirectory}/test_utils/find_test_subject.ts`, }, coverageDirectory: '/../target/kibana-coverage/jest', - coverageReporters: [ - 'html', - ], + coverageReporters: ['html'], setupFiles: [ `${kibanaDirectory}/src/dev/jest/setup/babel_polyfill.js`, `/dev-tools/jest/setup/polyfills.js`, `/dev-tools/jest/setup/enzyme.js`, ], setupFilesAfterEnv: [`${kibanaDirectory}/src/dev/jest/setup/mocks.js`], + testEnvironment: 'jest-environment-jsdom-fourteen', testMatch: ['**/*.test.{js,ts,tsx}'], transform: { '^.+\\.(js|tsx?)$': `${kibanaDirectory}/src/dev/jest/babel_transform.js`, diff --git a/x-pack/legacy/plugins/canvas/external_runtime/__mocks__/supported_renderers.js b/x-pack/legacy/plugins/canvas/external_runtime/__mocks__/supported_renderers.js new file mode 100644 index 0000000000000..937299ee85f87 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/external_runtime/__mocks__/supported_renderers.js @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import ReactDOM from 'react-dom'; +import React from 'react'; + +const renderers = [ + 'debug', + 'error', + 'image', + 'repeatImage', + 'revealImage', + 'markdown', + 'metric', + 'pie', + 'plot', + 'progress', + 'shape', + 'table', + 'text', +]; + +export const renderFunctions = renderers.map(fn => () => ({ + name: fn, + displayName: fn, + help: fn, + reuseDomNode: true, + render: domNode => { + ReactDOM.render(
{fn} mock
, domNode); + }, +})); diff --git a/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/__snapshots__/embed.test.tsx.snap b/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/__snapshots__/embed.test.tsx.snap new file mode 100644 index 0000000000000..4ca527be74d24 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/__snapshots__/embed.test.tsx.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Embed API Embeds successfully with default properties 1`] = `"
"`; + +exports[`Embed API Embeds successfully with default properties 2`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; + +exports[`Embed API Embeds successfully with height specified 1`] = `"
"`; + +exports[`Embed API Embeds successfully with height specified 2`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; + +exports[`Embed API Embeds successfully with page specified 1`] = `"
"`; + +exports[`Embed API Embeds successfully with page specified 2`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; + +exports[`Embed API Embeds successfully with page specified 3`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; + +exports[`Embed API Embeds successfully with width and height specified 1`] = `"
"`; + +exports[`Embed API Embeds successfully with width and height specified 2`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; + +exports[`Embed API Embeds successfully with width specified 1`] = `"
"`; + +exports[`Embed API Embeds successfully with width specified 2`] = ` +"
markdown mock
markdown mock
My Canvas Workpad
" +`; diff --git a/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/embed.test.tsx b/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/embed.test.tsx new file mode 100644 index 0000000000000..1845006cc6cf9 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/external_runtime/api/__tests__/embed.test.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount } from 'enzyme'; +import React from 'react'; +import { snapshots, tick } from '../../test'; +import { embed } from '../embed'; + +jest.mock('../../supported_renderers'); + +describe('Embed API', () => { + beforeEach(function() { + // @ts-ignore Applying a global in Jest is alright. + global.fetch = jest.fn().mockImplementation(() => { + const p = new Promise((resolve, _reject) => { + resolve({ + ok: true, + json: () => { + return snapshots.hello; + }, + }); + }); + return p; + }); + }); + + test('Embeds successfully with default properties', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const wrapper = mount(
, { + attachTo: container, + }); + + expect(wrapper.html()).toMatchSnapshot(); + embed(); + await tick(); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('Embeds successfully with height specified', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const wrapper = mount( +
, + { + attachTo: container, + } + ); + + expect(wrapper.html()).toMatchSnapshot(); + embed(); + await tick(); + expect(wrapper.html()).toMatch( + /
/ + ); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('Embeds successfully with width specified', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const wrapper = mount( +
, + { + attachTo: container, + } + ); + + expect(wrapper.html()).toMatchSnapshot(); + embed(); + await tick(); + expect(wrapper.html()).toMatch( + /
/ + ); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('Embeds successfully with width and height specified', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const wrapper = mount( +
, + { + attachTo: container, + } + ); + + expect(wrapper.html()).toMatchSnapshot(); + embed(); + await tick(); + expect(wrapper.html()).toMatch( + /
/ + ); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('Embeds successfully with page specified', async () => { + const container = document.createElement('div'); + document.body.appendChild(container); + const wrapper = mount( +
, + { + attachTo: container, + } + ); + + expect(wrapper.html()).toMatchSnapshot(); + embed(); + await tick(); + expect(wrapper.html()).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/canvas/external_runtime/api/embed.tsx b/x-pack/legacy/plugins/canvas/external_runtime/api/embed.tsx index a6a8ebc96ba6a..2729015bf51c5 100644 --- a/x-pack/legacy/plugins/canvas/external_runtime/api/embed.tsx +++ b/x-pack/legacy/plugins/canvas/external_runtime/api/embed.tsx @@ -10,16 +10,35 @@ import { App } from '../components/app'; import { CanvasRenderedWorkpad } from '../types'; export interface Options { - /** The preferred height to scale the embedded workpad. If only `height` is + /** + * The preferred height to scale the embedded workpad. If only `height` is * specified, `width` will be calculated by the workpad ratio. If both are - * specified, the ratio will be overriden by an absolute size. */ + * specified, the ratio will be overriden by an absolute size. + */ height?: number; - /** The preferred width to scale the embedded workpad. If only `width` is + /** + * The preferred width to scale the embedded workpad. If only `width` is * specified, `height` will be calculated by the workpad ratio. If both are - * specified, the ratio will be overriden by an absolute size. */ + * specified, the ratio will be overriden by an absolute size. + */ width?: number; /** The initial page to display. */ page?: number; + /** + * Should the runtime automatically move through the pages of the workpad? + * @default false + */ + autoplay?: boolean; + /** + * The interval upon which the pages will advance in time format, (e.g. 2s, 1m) + * @default '5s' + * */ + interval?: string; + /** + * Should the toolbar be hidden? + * @default false + */ + toolbar?: boolean; } const PREFIX = 'kbn-canvas'; @@ -51,12 +70,15 @@ const getWorkpad = async (url: string): Promise => }; const updateArea = async (area: Element) => { - const { url, page: pageAttr, height: heightAttr, weight: widthAttr } = getAttributes(area, [ - 'url', - 'page', - 'height', - 'width', - ]); + const { + url, + page: pageAttr, + height: heightAttr, + width: widthAttr, + autoplay, + interval, + toolbar, + } = getAttributes(area, ['url', 'page', 'height', 'width', 'autoplay', 'interval', 'toolbar']); if (url) { const workpad = await getWorkpad(url); @@ -68,22 +90,32 @@ const updateArea = async (area: Element) => { if (height && !width) { // If we have a height but no width, the width should honor the workpad ratio. - width = workpad.width * (height / workpad.height); + width = Math.round(workpad.width * (height / workpad.height)); } else if (width && !height) { // If we have a width but no height, the height should honor the workpad ratio. - height = workpad.height * (width / workpad.width); + height = Math.round(workpad.height * (width / workpad.width)); } const stage = { height: height || workpad.height, width: width || workpad.width, - page: page ? page : workpad.page, + page: page !== null ? page : workpad.page, + }; + + const settings = { + autoplay: { + isEnabled: !!autoplay, + interval: interval || '5s', + }, + toolbar: { + isAutohide: !!toolbar, + }, }; area.classList.add('kbnCanvas'); area.removeAttribute(EMBED); - render(, area); + render(, area); } } }; diff --git a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx b/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx deleted file mode 100644 index 7d26b0a5d05e9..0000000000000 --- a/x-pack/legacy/plugins/canvas/external_runtime/components/__examples__/footer.examples.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { storiesOf } from '@storybook/react'; -import React from 'react'; -import { Context } from '../../context/mock'; - -import { Footer } from '../footer/footer.container'; -import { Title } from '../footer/title.container'; -import { PageControls } from '../footer/page_controls.container'; -import { PagePreview } from '../footer/page_preview.container'; -import { Scrubber } from '../footer/scrubber.container'; - -storiesOf('runtime/Footer', module) - .add('Footer', () => ( - -