TinyLoader.setup(function (editor, onSuccess, onFailure) { const dialogSelector = 'div.tox-dialog'; const docBody = Element.fromDom(document.body); const editorBody = editor.contentDocument.body; const markupContent = '<p>hello world</p>'; const tinyApis = TinyApis(editor); Pipeline.async({}, [ Log.stepsAsStep('TBA', 'CodeSample: TBA-Open the dialog and check it has the right initial values. Set the codesample content, submit and check the editor content changes correctly. Double-click on the editor and check if the dialog opens with the correct language and content.', [ TestUtils.sOpenDialogAndAssertInitial(editor, docBody, 'markup', ''), TestUtils.sSetTextareaContent(markupContent), TestUtils.sSubmitDialog(docBody), TestUtils.sAssertEditorContents(editorBody, 'markup', markupContent, 'pre.language-markup'), Step.sync(function () { const pre = editor.getBody().querySelector('pre'); editor.fire('dblclick', { target: pre }); }), UiFinder.sWaitForVisible('Waited for dialog to be visible', docBody, dialogSelector), TestUtils.sAssertCodeSampleDialog('markup', markupContent), ]), Log.stepsAsStep('TBA', 'CodeSample: Selecting code sample should update button state', [ tinyApis.sSetContent('<p>abc</p><pre class="language-markup"><code></code></pre>'), tinyApis.sSelect('p', []), tinyApis.sNodeChanged, UiFinder.sNotExists(docBody, 'button[aria-pressed="true"]'), tinyApis.sSelect('pre.language-markup', []), tinyApis.sNodeChanged, UiFinder.sExists(docBody, 'button[aria-pressed="true"]'), ]), ] , onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyUi = TinyUi(editor); const sOpenDialog = () => { return GeneralSteps.sequence(Logger.ts('Open dialog and wait for it to be visible', [ tinyUi.sClickOnToolbar('click on preview toolbar', 'button'), tinyUi.sWaitForPopup('wait for preview popup', '[role="dialog"] iframe') ])); }; Pipeline.async({}, Log.steps('TBA', 'Preview: Set content, open dialog, click Close to close dialog. Open dialog, press escape and assert dialog closes', [ tinyApis.sSetContent('<strong>a</strong>'), sOpenDialog(), tinyUi.sClickOnUi('Click on Close button', '.tox-button:not(.tox-button--secondary)'), Waiter.sTryUntil('Dialog should close', UiFinder.sNotExists(docBody, dialogSelector), 100, 3000), sOpenDialog(), Keyboard.sKeydown(doc, Keys.escape(), { }), Waiter.sTryUntil('Dialog should close on esc', UiFinder.sNotExists(docBody, dialogSelector), 100, 3000) ]) , onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyActions = TinyActions(editor); Pipeline.async({}, Log.steps('TBA', 'Anchor: Add anchor by selecting text content, then check that anchor is inserted correctly', [ tinyApis.sFocus, tinyApis.sSetContent('<p>abc 123</p>'), tinyApis.sSetSelection([0, 0], 4, [0, 0], 7), tinyActions.sContentKeystroke(Keys.space(), {}), tinyApis.sExecCommand('mceanchor'), Chain.asStep(Element.fromDom(document.body), [ Chain.fromParent(UiFinder.cWaitForVisible('wait for dialog', 'div[role="dialog"].tox-dialog'), [ Chain.fromChains([ UiFinder.cFindIn('input'), UiControls.cSetValue('abc') ]), Chain.fromChains([ UiFinder.cFindIn('button:contains("Save")'), Mouse.cClick ]) ] ) ]), tinyApis.sAssertContent('<p>abc <a id="abc"></a>123</p>') ]) , onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyActions = TinyActions(editor); Pipeline.async({}, [ tinyApis.sFocus, tinyApis.sSetContent('<p>abc 123</p>'), tinyApis.sSetSelection([0, 0], 4, [0, 0], 7), tinyActions.sContentKeystroke(Keys.space(), {}), tinyApis.sExecCommand('mceanchor'), Chain.asStep(Element.fromDom(document.body), [ Chain.fromParent(UiFinder.cWaitForVisible('wait for dialog', 'div[aria-label="Anchor"][role="dialog"]'), [ Chain.fromChains([ UiFinder.cFindIn('input'), UiControls.cSetValue('abc') ]), Chain.fromChains([ UiFinder.cFindIn('button:contains("Ok")'), Mouse.cClick ]) ] ) ]), tinyApis.sAssertContent('<p>abc <a id="abc"></a>123</p>') ], onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyUi = TinyUi(editor); Pipeline.async({}, [ tinyApis.sFocus, tinyUi.sClickOnToolbar('click emoticons', 'button'), Chain.asStep({}, [ tinyUi.cWaitForPopup('wait for popup', 'div[role="dialog"]'), ]), Waiter.sTryUntil( 'Wait for emojis to load', UiFinder.sNotExists(Body.body(), '.tox-spinner'), 100, 1000 ), Chain.asStep(Body.body(), [ UiFinder.cFindAllIn('[role="tab"]'), Chain.mapper((elements: Element[]) => { return Arr.map(elements, (elm: Element) => { return elm.dom().textContent; }); }), Assertions.cAssertEq('Categories match', categories) ]) ], onSuccess, onFailure); }, {
TinyLoader.setup((editor, onSuccess, onFailure) => { const sSetProgressState = (state: boolean, time?: number) => Step.sync(() => { if (state) { editor.setProgressState(true, time); } else { editor.setProgressState(false); } }); Pipeline.async({}, [ Log.stepsAsStep('TBA', 'Throbber actions test', [ sAssertThrobberHiddenStructure, sSetProgressState(true), UiFinder.sWaitForVisible('Wait for throbber to show', Body.body(), '.tox-throbber'), sAssertThrobberShownStructure, sSetProgressState(false), UiFinder.sWaitForHidden('Wait for throbber to hide', Body.body(), '.tox-throbber'), sAssertThrobberHiddenStructure ]), Log.stepsAsStep('TBA', 'Throbber actions with timeout test', [ sSetProgressState(true, 300), // Wait for a little and make sure the throbber is still hidden Step.wait(150), sAssertThrobberHiddenStructure, UiFinder.sWaitForVisible('Wait for throbber to show', Body.body(), '.tox-throbber'), sAssertThrobberShownStructure, sSetProgressState(false), UiFinder.sWaitForHidden('Wait for throbber to hide', Body.body(), '.tox-throbber'), sAssertThrobberHiddenStructure ]) ], onSuccess, onFailure); }, {
TinyLoader.setup((editor, onSuccess, onFailure) => { const tinyApis = TinyApis(editor); const dialogSelector = 'div.tox-dialog'; const toolbarButtonSelector = '[role="toolbar"] button[aria-label="Insert template"]'; const docBody = Element.fromDom(document.body); Pipeline.async({}, [ Log.stepsAsStep('TBA', 'Template: Test selectedcontent replacement with default class', [ tinyApis.sSetContent('Text'), tinyApis.sSetSelection([0, 0], 0, [0, 0], 4), tinyApis.sSetSetting('templates', [{ title: 'a', description: 'b', content: '<h1 class="selcontent">This will be replaced</h1>' }]), Mouse.sClickOn(Element.fromDom(editor.getContainer()), toolbarButtonSelector), UiFinder.sWaitForVisible('Waited for dialog to be visible', docBody, dialogSelector), Mouse.sClickOn(docBody, 'button.tox-button:contains(Save)'), Waiter.sTryUntil('Dialog should close', UiFinder.sNotExists(docBody, dialogSelector), 100, 3000), tinyApis.sAssertContent('<h1 class="selcontent">Text</h1>') ]), Log.stepsAsStep('TBA', 'Template: Test selectedcontent replacement with custom class', [ tinyApis.sSetContent('Text'), tinyApis.sSetSelection([0, 0], 0, [0, 0], 4), tinyApis.sSetSetting('template_selected_content_classes', 'customSelected'), tinyApis.sSetSetting('templates', [{ title: 'a', description: 'b', content: '<h1 class="customSelected">This will be replaced/h1>' }]), Mouse.sClickOn(Element.fromDom(editor.getContainer()), toolbarButtonSelector), UiFinder.sWaitForVisible('Waited for dialog to be visible', docBody, dialogSelector), Mouse.sClickOn(docBody, 'button.tox-button:contains(Save)'), Waiter.sTryUntil('Dialog should close', UiFinder.sNotExists(docBody, dialogSelector), 100, 3000), tinyApis.sAssertContent('<h1 class="customSelected">Text</h1>') ]) ], onSuccess, onFailure); }, {
(editor, onSuccess, onFailure) => { const doc = Element.fromDom(document); Pipeline.async({ }, Log.steps( 'TBA', 'Check structure of table picker', [ Mouse.sClickOn(Body.body(), '.tox-toolbar button'), UiFinder.sWaitForVisible('Waiting for menu', Body.body(), '[role="menu"]'), Chain.asStep(Body.body(), [ UiFinder.cFindIn('[role="menu"]'), Assertions.cAssertStructure( 'Checking structure', ApproxStructure.build((s, str, arr) => insertTablePickerApprox(s, str, arr, 1, 1)) ) ]), FocusTools.sTryOnSelector('Focus should be on first table cell', doc, '.tox-insert-table-picker__selected:last'), Keyboard.sKeydown(doc, Keys.down(), {}), Keyboard.sKeydown(doc, Keys.right(), {}), Chain.asStep(Body.body(), [ UiFinder.cFindIn('[role="menu"]'), Assertions.cAssertStructure( 'Checking structure', ApproxStructure.build((s, str, arr) => insertTablePickerApprox(s, str, arr, 2, 2)) ) ]), FocusTools.sTryOnSelector('Focus should be on 2 down, 2 across table cell', doc, '.tox-insert-table-picker__selected:last') ] ), onSuccess, onFailure); },
const testChangingUrlValueWith = (sChooseItem: Step<any, any>) => Log.stepsAsStep('TBA', 'Link: Choosing something in the urlinput changes text and value', [ tinyApis.sSetContent('<h1>Header One</h1><h2 id="existing-id">Header2</h2>'), TestLinkUi.sOpenLinkDialog, Keyboard.sKeydown(doc, Keys.down(), { }), UiFinder.sWaitForVisible('Waiting for dropdown', TinyDom.fromDom(document.body), '.tox-menu'), sChooseItem, sAssertUrlStructure((s, str, _arr) => { return s.element('input', { value: str.startsWith('#h_') }); }), sAssertInputValue('Header One', 'Text to display'), TestLinkUi.sAssertContentPresence(tinyApis, { 'h1[id]': 0, 'h2[id]': 1 }), TestLinkUi.sClickSave, TestLinkUi.sAssertContentPresence(tinyApis, { 'h1[id]': 1 }), // Check that the h1's id value is referred to by a link containing dog Chain.asStep(TinyDom.fromDom(editor.getBody()), [ NamedChain.asChain([ NamedChain.direct(NamedChain.inputName(), UiFinder.cFindIn('h1'), 'h1'), NamedChain.direct('h1', Chain.mapper((h1) => Attr.get(h1, 'id')), 'h1-id'), NamedChain.bundle((obj) => { return UiFinder.findIn(obj[NamedChain.inputName()], `a[href="#${obj['h1-id']}"]:contains("Header One")`); }) ]) ]) ]);
(editor, onSuccess, onFailure) => { const doc = Element.fromDom(document); Pipeline.async({ }, Logger.ts( 'Check structure of grid collection menu', [ TestHelpers.GuiSetup.mAddStyles(doc, [ ':focus { background-color: rgb(222, 224, 226); }' ]), Mouse.sClickOn(Body.body(), '.tox-split-button__chevron'), UiFinder.sWaitForVisible('Waiting for menu', Body.body(), '[role="menu"]'), Chain.asStep(Body.body(), [ UiFinder.cFindIn('[role="menu"]'), Assertions.cAssertStructure( 'Checking structure', ApproxStructure.build((s, str, arr) => { return s.element('div', { classes: [ arr.has('tox-menu'), arr.has('tox-collection'), arr.has('tox-collection--grid') ], children: [ s.element('div', { classes: [ arr.has('tox-collection__group') ], children: Arr.map([ '1', '2', '3', '4', '5', '6', '7', '8' ], (num) => { return s.element('div', { classes: [ arr.has('tox-collection__item') ], attrs: { title: str.is(num) }, children: [ // NOTE: The oxide demo page has div, but I think that's just a mistake s.element('div', { classes: [ arr.has('tox-collection__item-icon') ], children: [ s.element('svg', {}) ] }) ] }); }) }) ] }); }) ) ]), // Without layout, the flatgrid cannot be calculated on phantom navigator.userAgent.indexOf('PhantomJS') > -1 ? Step.pass : GeneralSteps.sequence([ FocusTools.sTryOnSelector('Focus should be on 1', doc, '.tox-collection__item[title="1"]'), Keyboard.sKeydown(doc, Keys.right(), { }), FocusTools.sTryOnSelector('Focus should be on 2', doc, '.tox-collection__item[title="2"]'), Keyboard.sKeydown(doc, Keys.right(), { }), FocusTools.sTryOnSelector('Focus should be on 3', doc, '.tox-collection__item[title="3"]') ]), TestHelpers.GuiSetup.mRemoveStyles ] ), onSuccess, onFailure); },