UNPKG

@kui-shell/plugin-client-common

Version:

Kui plugin that offers stylesheets

307 lines 15.5 kB
/* * Copyright 2022 The Kubernetes Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { basename, dirname, join } from 'path'; import { encodeComponent } from '@kui-shell/core'; import { Common, CLI, ReplExpect, Selectors, Util } from '@kui-shell/test'; const ROOT = join(dirname(require.resolve('@kui-shell/plugin-client-common/notebooks/wizard.md')), '..'); const steps = [ { name: 'Step1Title', description: 'Step1Description', body: 'Step1Body', codeBlocks: [{ index: 0, output: 'aaa' }] }, { name: 'Step2Title', description: 'Step2Description', body: 'Step2Body', codeBlocks: [ { index: 1, output: 'bbb' }, { index: 2, output: 'ccc' } ] } ]; const IN1 = { input: join(ROOT, 'notebooks/wizard.md'), title: 'WizardTitle', description: 'WizardDescription', steps, expectedSplitCount: 1, expectedCodeBlockTasks: 3 }; // make sure we can display wizards in tabs with splits const IN2 = { input: join(ROOT, 'tests/data/wizard-with-splits.md'), title: 'WizardTitleWithSplits', description: 'WizardDescriptionWithSplits', steps, expectedSplitCount: 2, expectedCodeBlockTasks: IN1.expectedCodeBlockTasks }; // make sure we can display wizards in tabs with splits const IN3 = { input: join(ROOT, 'tests/data/wizard-steps-in-topmatter.md'), title: 'Getting Started with Knative', description: 'WizardDescriptionInTopmatter', expectedSplitCount: 1, expectedCodeBlockTasks: 12, steps: [ { name: 'Install the Knative quickstart plugin', body: 'To get started, install the Knative', description: 'TestDescription2', codeBlocks: [] }, { name: 'TestRewritingOfStepName', body: 'plugin completes the following functions', description: 'This will quickly set up Knative against kind or minikube', codeBlocks: [] }, { name: 'Next steps', body: "Now you've installed Knative", description: '', codeBlocks: [] } ], // the guide does not yet show non-code block steps // i don't think we'll ever want this? notIn: (command) => command === 'guide' }; // sequential execution of code blocks const IN4 = { input: join(ROOT, 'tests/data/wizard-steps-in-topmatter2.md'), title: 'WizardTitle', description: 'WizardDescription', expectedSplitCount: 1, expectedCodeBlockTasks: 3, steps: [ { name: 'AAA', body: 'AAAContent', description: '', codeBlocks: [{ index: 0, output: '111' }] }, { name: 'BBB', body: 'BBBContent', description: '', codeBlocks: [{ index: 1, output: '222' }] }, { name: 'CCC', body: 'CCCContent', description: '', codeBlocks: [{ index: 2, output: '333' }] } ] }; const aaaBody = (command) => (command === 'guide' ? 'Tab11' : 'AAAContent'); // nested choice const IN5 = { input: join(ROOT, 'tests/data/nested-choice1.md'), title: 'WizardTitle', description: 'WizardDescription', expectedSplitCount: 1, expectedCodeBlockTasks: 2, steps: [{ name: 'AAA', body: aaaBody, description: '', codeBlocks: [{ index: 0, output: 'XXX' }] }] }; // nested choice const IN6 = { input: join(ROOT, 'tests/data/nested-choice2.md'), title: 'WizardTitle', description: 'WizardDescription', expectedSplitCount: 1, expectedCodeBlockTasks: 3, steps: [ { name: 'AAA', body: aaaBody, description: '', codeBlocks: [ { index: 0, output: 'XXX1' }, { index: 1, output: 'XXX2' } ] } ] }; [IN1, IN2, IN3, IN4, IN5, IN6].forEach(markdown => { ; ['guide', 'commentary -f'].forEach(command => { if (markdown.notIn && markdown.notIn(command)) { return; } describe(`wizards in markdown command="${command}" input="${basename(markdown.input)}" ${process.env.MOCHA_RUN_TARGET || ''}`, function () { before(Common.before(this)); after(Common.after(this)); Util.closeAllExceptFirstTab.bind(this)(); it('should load markdown and show a wizard UI', () => __awaiter(this, void 0, void 0, function* () { try { yield CLI.command(`${command} ${encodeComponent(markdown.input)}`, this.app); yield this.app.client.$(Selectors.Wizard.wizard).then(_ => _.waitForExist({ timeout: CLI.waitTimeout })); } catch (err) { yield Common.oops(this, true)(err); } })); it(`should show wizard title ${markdown.title}`, () => this.app.client .$(Selectors.Wizard.withTitle(markdown.title)) .then(_ => _.waitForExist({ timeout: CLI.waitTimeout })) .catch(Common.oops(this, true))); it(`should show wizard description ${markdown.description}`, () => __awaiter(this, void 0, void 0, function* () { try { const elt = yield this.app.client.$(Selectors.Wizard.description); yield elt.waitForExist({ timeout: CLI.waitTimeout }); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { const actualText = yield elt.getText(); return actualText.includes(markdown.description); }), { timeout: CLI.waitTimeout }); } catch (err) { yield Common.oops(this, true)(err); } })); if (command !== 'guide') { it(`should show "n of ${markdown.expectedCodeBlockTasks}" in progress bar`, () => { let iter = 0; return this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { const actualMeasureText = yield this.app.client.$(Selectors.Wizard.progressMeasure).then(_ => _.getText()); const match = actualMeasureText.match(/of (\d+)/); const actualN = match && match[1] && parseInt(match[1], 10); const expectedN = markdown.expectedCodeBlockTasks; if (++iter > 5) { console.error('Still waiting for wizard task count', iter, actualN, expectedN, '||', match, '||', actualMeasureText); } return actualN === expectedN; })); }); it(`should have ${markdown.expectedSplitCount} splits`, () => ReplExpect.splitCount(markdown.expectedSplitCount)); } markdown.steps.forEach((step, idx) => { if (idx === 0) { const body = typeof step.body === 'string' ? step.body : step.body(command); it(`should show wizard body ${body}`, () => __awaiter(this, void 0, void 0, function* () { try { const elt = yield this.app.client.$(Selectors.Wizard.body); yield elt.waitForExist({ timeout: CLI.waitTimeout }); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { const actualText = yield elt.getText(); return actualText.includes(body); }), { timeout: CLI.waitTimeout }); } catch (err) { yield Common.oops(this, true)(err); } })); } it(`should show nav item ${idx} title ${step.name}`, () => __awaiter(this, void 0, void 0, function* () { try { const elt = yield this.app.client.$(Selectors.Wizard.navItemTitle(idx)); yield elt.waitForExist({ timeout: CLI.waitTimeout }); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { const actualText = yield elt.getText(); return actualText === step.name; }), { timeout: CLI.waitTimeout }); } catch (err) { yield Common.oops(this, true)(err); } })); if (step.description) { it(`should show nav item ${idx} description ${step.description}`, () => __awaiter(this, void 0, void 0, function* () { try { const elt = yield this.app.client.$(Selectors.Wizard.navItemDescription(idx)); yield elt.waitForExist({ timeout: CLI.waitTimeout }); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { const actualText = yield elt.getText(); return actualText === step.description; }), { timeout: CLI.waitTimeout }); } catch (err) { yield Common.oops(this, true)(err); } })); } if (command !== 'guide') { step.codeBlocks.forEach((codeBlock, codeBlockIdx) => { it(`should show nav item ${idx} progress step ${codeBlockIdx}`, () => __awaiter(this, void 0, void 0, function* () { try { const elt = yield this.app.client.$(Selectors.Wizard.navItemProgressStep(idx, codeBlockIdx)); yield elt.waitForExist({ timeout: CLI.waitTimeout }); } catch (err) { yield Common.oops(this, true)(err); } })); }); } }); }); describe(`sequential execution of code blocks in wizards in markdown ${basename(markdown.input)} ${process.env.MOCHA_RUN_TARGET || ''}`, function () { before(Common.before(this)); after(Common.after(this)); Util.closeAllExceptFirstTab.bind(this)(); it('should load markdown and show a wizard UI', () => __awaiter(this, void 0, void 0, function* () { try { yield CLI.command(`commentary -f ${encodeComponent(markdown.input)}`, this.app); yield this.app.client.$(Selectors.Wizard.wizard).then(_ => _.waitForExist({ timeout: CLI.waitTimeout })); } catch (err) { yield Common.oops(this, true)(err); } })); const stepsWithCodeBlocks = markdown.steps .map((step, idx) => ({ step, idx })) .filter(_ => Array.isArray(_.step.codeBlocks) && _.step.codeBlocks.length > 0); if (stepsWithCodeBlocks.length > 1) { it('should show a play button for the first code blocks in the first step (with code blocks)', () => __awaiter(this, void 0, void 0, function* () { try { const firstBlockInFirstStep = stepsWithCodeBlocks[0].step.codeBlocks[0]; const codeBlock = yield this.app.client.$(Selectors.Markdown.codeBlock(firstBlockInFirstStep.index)); yield codeBlock.waitForExist({ timeout: CLI.waitTimeout }); yield codeBlock.$(Selectors.Markdown.runButton).then(_ => _.waitForExist({ timeout: CLI.waitTimeout })); } catch (err) { yield Common.oops(this, true)(err); } })); stepsWithCodeBlocks.slice(1).forEach(({ step, idx }) => { it(`should switch to step ${idx}`, () => __awaiter(this, void 0, void 0, function* () { try { const button = yield this.app.client.$(Selectors.Wizard.navItemSwitchToButton(idx)); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { return !(yield button.getAttribute('class')).includes(Selectors.Wizard.isCurrentStep); })); yield button.waitForExist({ timeout: CLI.waitTimeout }); yield button.click(); yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () { return (yield button.getAttribute('class')).includes(Selectors.Wizard.isCurrentStep); })); } catch (err) { yield Common.oops(this, true)(err); } })); step.codeBlocks.forEach(block => { it(`should *not* show a play button for code block ${block.index} in step ${idx}`, () => __awaiter(this, void 0, void 0, function* () { try { const codeBlock = yield this.app.client.$(Selectors.Markdown.codeBlock(block.index)); yield codeBlock.waitForExist({ timeout: CLI.waitTimeout }); yield codeBlock .$(Selectors.Markdown.runButton) .then(_ => _.waitForDisplayed({ reverse: true, timeout: CLI.waitTimeout })); } catch (err) { yield Common.oops(this, true)(err); } })); }); }); } }); }); }); //# sourceMappingURL=wizards.js.map