diff --git a/.circleci/config.yml b/.circleci/config.yml index 863788fd2..385cf80b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -93,8 +93,13 @@ jobs: command: | set -e ./commands/cli/lib/index.js create generated/barchart --picasso barchart --no-install + echo "Yarn" yarn + echo "Linking packages" + npx lerna link --force-local cd generated/barchart + echo "Log node_modules/@nebula.js" + ls -la node_modules/@nebula.js yarn run build APP_ID=$DOC_ID yarn run test:integration --mocha.timeout 30000 --chrome.browserWSEndpoint "ws://localhost:3000" --no-launch diff --git a/apis/nucleus/src/components/Cell.jsx b/apis/nucleus/src/components/Cell.jsx index e94c26afd..9e0d4ec5a 100644 --- a/apis/nucleus/src/components/Cell.jsx +++ b/apis/nucleus/src/components/Cell.jsx @@ -16,6 +16,15 @@ import useLayout, { useAppLayout } from '../hooks/useLayout'; import InstanceContext from '../contexts/InstanceContext'; import useObjectSelections from '../hooks/useObjectSelections'; +/** + * @interface + * @extends HTMLElement + */ +const CellElement = { + /** @type {'njs-cell'} */ + className: 'njs-cell', +}; + const initialState = (err) => ({ loading: false, loaded: false, @@ -324,7 +333,7 @@ const Cell = forwardRef(({ halo, model, initialSnOptions, initialError, onMount style={{ position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }} elevation={0} square - className="nebulajs-cell" + className={CellElement.className} ref={cellRef} onMouseEnter={handleOnMouseEnter} onMouseLeave={handleOnMouseLeave} diff --git a/apis/nucleus/src/components/Supernova.jsx b/apis/nucleus/src/components/Supernova.jsx index 551d36209..71e24541a 100644 --- a/apis/nucleus/src/components/Supernova.jsx +++ b/apis/nucleus/src/components/Supernova.jsx @@ -2,6 +2,16 @@ import React, { useState, useEffect, useCallback, useContext, useRef } from 'rea import InstanceContext from '../contexts/InstanceContext'; import useRect from '../hooks/useRect'; +/** + * @interface + * @extends HTMLElement + * @property {string} attributes.data-render-count + */ +const VizElement = { + /** @type {'njs-viz'} */ + className: 'njs-viz', +}; + const Supernova = ({ sn, snOptions: options, layout, appLayout, halo }) => { const { component } = sn; @@ -96,7 +106,7 @@ const Supernova = ({ sn, snOptions: options, layout, appLayout, halo }) => { ref={containerRef} data-render-count={renderCnt} style={{ position: 'relative', height: '100%' }} - className="nebulajs-sn" + className={VizElement.className} >
diff --git a/apis/nucleus/src/object/get-object.js b/apis/nucleus/src/object/get-object.js index b3887d697..5a2a64e03 100644 --- a/apis/nucleus/src/object/get-object.js +++ b/apis/nucleus/src/object/get-object.js @@ -3,7 +3,7 @@ import { modelStore, rpcRequestModelStore } from '../stores/modelStore'; /** * @interface BaseConfig - * @property {HTMLElement} element + * @property {CellElement} element * @property {object=} options */ diff --git a/apis/snapshooter/server.js b/apis/snapshooter/server.js index 34446fa6e..13c25dbb4 100644 --- a/apis/snapshooter/server.js +++ b/apis/snapshooter/server.js @@ -30,8 +30,8 @@ function snapshooter({ snapshotUrl, chrome = {} } = {}) { try { await page.waitFor( () => - (document.querySelector('.nebulajs-sn') && - +document.querySelector('.nebulajs-sn').getAttribute('data-render-count') > 0) || + (document.querySelector('.njs-viz') && + +document.querySelector('.njs-viz').getAttribute('data-render-count') > 0) || document.querySelector('[data-njs-error]') ); } catch (e) { diff --git a/apis/stardust/api-spec/spec.conf.js b/apis/stardust/api-spec/spec.conf.js index a9455b312..a46dccd11 100644 --- a/apis/stardust/api-spec/spec.conf.js +++ b/apis/stardust/api-spec/spec.conf.js @@ -3,6 +3,7 @@ module.exports = { glob: [ '!*.spec.js', '../nucleus/src/**/*.js', + '../nucleus/src/**/*.jsx', '../supernova/src/**/*.js', '../locale/src/translator.js', '../theme/src/**/*.js', diff --git a/apis/stardust/api-spec/spec.json b/apis/stardust/api-spec/spec.json index 7674f4cb0..24341a5b4 100644 --- a/apis/stardust/api-spec/spec.json +++ b/apis/stardust/api-spec/spec.json @@ -835,6 +835,50 @@ } } }, + "LoadType": { + "kind": "interface", + "params": [ + { + "name": "type", + "kind": "object", + "entries": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + } + } + ], + "returns": { + "type": "Promise", + "generics": [ + { + "type": "#/definitions/Visualization" + } + ] + }, + "entries": {} + }, + "TypeInfo": { + "kind": "interface", + "entries": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "load": { + "type": "#/definitions/LoadType" + }, + "meta": { + "optional": true, + "type": "object" + } + } + }, "CreateConfig": { "extends": [ { @@ -933,47 +977,39 @@ } } }, - "LoadType": { - "kind": "interface", - "params": [ + "CellElement": { + "extends": [ { - "name": "type", + "type": "HTMLElement" + } + ], + "kind": "interface", + "entries": { + "className": { + "value": "'njs-cell'", + "kind": "literal" + } + } + }, + "VizElement": { + "extends": [ + { + "type": "HTMLElement" + } + ], + "kind": "interface", + "entries": { + "attributes": { "kind": "object", "entries": { - "name": { - "type": "string" - }, - "version": { + "data-render-count": { "type": "string" } } - } - ], - "returns": { - "type": "Promise", - "generics": [ - { - "type": "#/definitions/Visualization" - } - ] - }, - "entries": {} - }, - "TypeInfo": { - "kind": "interface", - "entries": { - "name": { - "type": "string" }, - "version": { - "type": "string" - }, - "load": { - "type": "#/definitions/LoadType" - }, - "meta": { - "optional": true, - "type": "object" + "className": { + "value": "'njs-viz'", + "kind": "literal" } } }, diff --git a/commands/create/templates/sn/none/test/integration/hello.int.js b/commands/create/templates/sn/none/test/integration/hello.int.js index 07bc6b8da..a002a6ba2 100644 --- a/commands/create/templates/sn/none/test/integration/hello.int.js +++ b/commands/create/templates/sn/none/test/integration/hello.int.js @@ -1,5 +1,5 @@ describe('sn', () => { - const content = '.nebulajs-sn[data-render-count="1"]'; + const content = '.njs-viz[data-render-count="1"]'; it('should say hello', async () => { const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf'); await page.goto(`${process.env.BASE_URL}/render/?app=${app}`); diff --git a/commands/create/templates/sn/picasso/barchart/test/integration/interaction.int.js b/commands/create/templates/sn/picasso/barchart/test/integration/interaction.int.js index a14a904a1..58774a260 100644 --- a/commands/create/templates/sn/picasso/barchart/test/integration/interaction.int.js +++ b/commands/create/templates/sn/picasso/barchart/test/integration/interaction.int.js @@ -1,5 +1,5 @@ describe('interaction', () => { - const content = '.nebulajs-sn[data-render-count="1"]'; + const content = '.njs-viz[data-render-count="1"]'; it('should select two bars', async () => { const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf'); await page.goto(`${process.env.BASE_URL}/render/?app=${app}&cols=Alpha,=5+avg(Expression1)`); diff --git a/test/component/hooks/sn.comp.js b/test/component/hooks/sn.comp.js index 9e5b9ba81..6742d22b4 100644 --- a/test/component/hooks/sn.comp.js +++ b/test/component/hooks/sn.comp.js @@ -1,5 +1,5 @@ describe('hooks', () => { - const snSelector = '.nebulajs-sn'; + const snSelector = '.njs-viz'; before(async () => { await page.goto(`${process.env.BASE_URL}/render/?fixture=./hooks/hooked.fix.js`); @@ -8,74 +8,74 @@ describe('hooks', () => { it('usePromise', async () => { await page.waitForFunction( - selector => document.querySelector(selector).getAttribute('data-render-count') === '1', + (selector) => document.querySelector(selector).getAttribute('data-render-count') === '1', {}, `${snSelector}` ); - expect(await page.$eval(`${snSelector} .promise`, el => el.textContent)).to.equal('ready!'); + expect(await page.$eval(`${snSelector} .promise`, (el) => el.textContent)).to.equal('ready!'); }); it('should render with initial state', async () => { - const state = await page.$eval(`${snSelector} .state`, el => el.textContent); + const state = await page.$eval(`${snSelector} .state`, (el) => el.textContent); expect(state).to.equal('0'); - const action = await page.$eval(`${snSelector} .action`, el => el.textContent); + const action = await page.$eval(`${snSelector} .action`, (el) => el.textContent); expect(action).to.equal('false'); }); it('should update count state after first click', async () => { await page.click(snSelector); await page.waitForFunction( - selector => document.querySelector(selector).textContent === '1', + (selector) => document.querySelector(selector).textContent === '1', {}, `${snSelector} .state` ); - const text = await page.$eval(`${snSelector} .state`, el => el.textContent); + const text = await page.$eval(`${snSelector} .state`, (el) => el.textContent); expect(text).to.equal('1'); }); it('should update action state after second click', async () => { await page.click(snSelector); await page.waitForFunction( - selector => document.querySelector(selector).textContent === 'true', + (selector) => document.querySelector(selector).textContent === 'true', {}, `${snSelector} .action` ); - const text = await page.$eval(`${snSelector} .action`, el => el.textContent); + const text = await page.$eval(`${snSelector} .action`, (el) => el.textContent); expect(text).to.equal('true'); }); it('useLayout', async () => { - const text = await page.$eval(`${snSelector} .layout`, el => el.textContent); + const text = await page.$eval(`${snSelector} .layout`, (el) => el.textContent); expect(text).to.equal('true'); }); it('useAppLayout', async () => { - const text = await page.$eval(`${snSelector} .applayout`, el => el.textContent); + const text = await page.$eval(`${snSelector} .applayout`, (el) => el.textContent); expect(text).to.equal('app-title'); }); it('useTranslator', async () => { - const text = await page.$eval(`${snSelector} .translator`, el => el.textContent); + const text = await page.$eval(`${snSelector} .translator`, (el) => el.textContent); expect(text).to.equal('Cancel'); }); it('useTheme', async () => { - const text = await page.$eval(`${snSelector} .theme`, el => el.textContent); + const text = await page.$eval(`${snSelector} .theme`, (el) => el.textContent); expect(text).to.equal('#a54343'); }); it('useConstraints', async () => { - const text = await page.$eval(`${snSelector} .constraints`, el => el.textContent); + const text = await page.$eval(`${snSelector} .constraints`, (el) => el.textContent); expect(text).to.equal('false:false:true'); }); it('useOptions', async () => { - const text = await page.$eval(`${snSelector} .options`, el => el.textContent); + const text = await page.$eval(`${snSelector} .options`, (el) => el.textContent); expect(text).to.equal('opts'); }); it('should have true MAGIC_FLAG', async () => { - const text = await page.$eval(`${snSelector} .flags`, el => el.textContent); + const text = await page.$eval(`${snSelector} .flags`, (el) => el.textContent); expect(text).to.equal('true:false'); }); }); diff --git a/test/component/object/sn.comp.js b/test/component/object/sn.comp.js index 2dfe04de1..0a58d0044 100644 --- a/test/component/object/sn.comp.js +++ b/test/component/object/sn.comp.js @@ -1,12 +1,12 @@ describe('sn', () => { - const snSelector = '.nebulajs-sn'; - const errorSelector = '.nebulajs-cell [data-tid="error-title"]'; + const snSelector = '.njs-viz'; + const errorSelector = '.njs-cell [data-tid="error-title"]'; it('should render with translation', async () => { await page.goto(`${process.env.BASE_URL}/render/?fixture=./object/sn-locale.fix.js&language=sv-SE`); await page.waitForSelector(snSelector, { visible: true }); - const text = await page.$eval(snSelector, el => el.textContent); + const text = await page.$eval(snSelector, (el) => el.textContent); expect(text).to.equal('Hej motor!'); }); @@ -14,7 +14,7 @@ describe('sn', () => { await page.goto(`${process.env.BASE_URL}/render/?fixture=./object/sn-incomplete.fix.js&theme=dark `); await page.waitForSelector(errorSelector, { visible: true }); - const text = await page.$eval(errorSelector, el => el.textContent); + const text = await page.$eval(errorSelector, (el) => el.textContent); expect(text).to.equal('Incomplete visualization'); }); @@ -22,7 +22,7 @@ describe('sn', () => { await page.goto(`${process.env.BASE_URL}/render/?fixture=./object/sn-error.fix.js`); await page.waitForSelector(errorSelector, { visible: true }); - const text = await page.$eval(errorSelector, el => el.textContent); + const text = await page.$eval(errorSelector, (el) => el.textContent); expect(text).to.equal('hahaha'); }); }); diff --git a/test/integration/sn.int.js b/test/integration/sn.int.js index 0231aaed0..f0416fba2 100644 --- a/test/integration/sn.int.js +++ b/test/integration/sn.int.js @@ -1,12 +1,12 @@ describe('sn', () => { - const content = '.nebulajs-sn'; + const content = '.njs-viz'; it('should say hello', async () => { const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf'); await page.goto(`${process.env.BASE_URL}/render/?app=${app}`); await page.waitForSelector(content, { visible: true }); - const text = await page.$eval(content, el => el.textContent); + const text = await page.$eval(content, (el) => el.textContent); expect(text).to.equal('Hello engine!'); }); }); diff --git a/test/mashup/snaps/snapper.int.js b/test/mashup/snaps/snapper.int.js index d1925e0aa..7392575a3 100644 --- a/test/mashup/snaps/snapper.int.js +++ b/test/mashup/snaps/snapper.int.js @@ -22,14 +22,14 @@ const d = differ(); describe('snapper', () => { const object = '[data-type="bar"]'; - const selector = `${object} .nebulajs-sn`; + const selector = `${object} .njs-viz`; it('should capture an image of a bar', async () => { await page.goto(`${process.env.BASE_URL}/snaps/snapper.html`); await page.waitForSelector(selector, { visible: true }); await page.click(selector); await page.waitForSelector(`${object}[data-captured]`, { visible: true }); - const imgSrc = await page.$eval(`${object}[data-captured]`, el => el.getAttribute('data-captured')); + const imgSrc = await page.$eval(`${object}[data-captured]`, (el) => el.getAttribute('data-captured')); const captured = await jimp.read(`${process.env.BASE_URL}${imgSrc}`); await d.looksLike('bar.png', captured);