TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyActions = TinyActions(editor); Pipeline.async({}, [ Logger.t('Press space at beginning of inline boundary', GeneralSteps.sequence([ tinyApis.sFocus, tinyApis.sSetContent('<p>a <a href="#">b</a> c</p>'), tinyApis.sSetCursor([0, 1, 0], 0), tinyApis.sNodeChanged, tinyActions.sContentKeystroke(Keys.space(), {}), tinyApis.sAssertSelection([0, 1, 0], 1, [0, 1, 0], 1), tinyApis.sAssertContent('<p>a <a href="#"> b</a> c</p>') ])), Logger.t('Press space at end of inline boundary', GeneralSteps.sequence([ tinyApis.sFocus, tinyApis.sSetContent('<p>a <a href="#">b</a> c</p>'), tinyApis.sSetCursor([0, 1, 0], 1), tinyApis.sNodeChanged, tinyActions.sContentKeystroke(Keys.space(), {}), tinyApis.sAssertSelection([0, 1, 0], 2, [0, 1, 0], 2), tinyApis.sAssertContent('<p>a <a href="#">b </a> c</p>') ])) ], onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyActions = TinyActions(editor); Pipeline.async({}, [ tinyApis.sFocus, Logger.t('Type text before cef inline element', GeneralSteps.sequence([ tinyApis.sSetContent('<p><span contenteditable="false">a</span></p>'), tinyApis.sSelect('p', [1]), tinyActions.sContentKeystroke(Keys.left(), {}), TypeText.sTypeContentAtSelection(Element.fromDom(editor.getDoc()), 'bc'), tinyApis.sAssertSelection([0, 0], 2, [0, 0], 2), tinyApis.sAssertContent('<p>bc<span contenteditable="false">a</span></p>') ])), Logger.t('Type after cef inline element', GeneralSteps.sequence([ tinyApis.sSetContent('<p><span contenteditable="false">a</span></p>'), tinyApis.sSelect('p', [1]), tinyActions.sContentKeystroke(Keys.right(), {}), TypeText.sTypeContentAtSelection(Element.fromDom(editor.getDoc()), 'bc'), tinyApis.sAssertSelection([0, 1], 3, [0, 1], 3), tinyApis.sAssertContent('<p><span contenteditable="false">a</span>bc</p>') ])), Logger.t('Type between cef inline elements', GeneralSteps.sequence([ tinyApis.sSetContent('<p><span contenteditable="false">a</span> <span contenteditable="false">b</span></p>'), tinyApis.sSelect('p', [3]), tinyActions.sContentKeystroke(Keys.left(), {}), tinyActions.sContentKeystroke(Keys.left(), {}), TypeText.sTypeContentAtSelection(Element.fromDom(editor.getDoc()), 'bc'), tinyApis.sAssertSelection([0, 1], 3, [0, 1], 3), tinyApis.sAssertContent('<p><span contenteditable="false">a</span>bc <span contenteditable="false">b</span></p>') ])) ], onSuccess, onFailure); }, {
const sTestArrowsAnchorSurroundedByText = function (tinyApis, tinyActions, editor) { return Logger.t('sTestArrowsAnchorSurroundedByText', GeneralSteps.sequence([ tinyApis.sSetContent('<p>a<a href="#">b</a>c</p>'), tinyApis.sSetCursor([0, 1, 0], 0), tinyApis.sNodeChanged, sAssertCursor(tinyApis, [0, 1, 0], 1), sAssertContentStructure(editor, anchorSurroundedWithZwspInside(START)), tinyActions.sContentKeystroke(Keys.left(), { }), sAssertCursor(tinyApis, [0, 0], 1), sAssertContentStructure(editor, anchorSurroundedWithZwspOutside(BEFORE)), tinyActions.sContentKeystroke(Keys.right(), { }), sAssertCursor(tinyApis, [0, 1, 0], 1), sAssertContentStructure(editor, anchorSurroundedWithZwspInside(START)), tinyActions.sContentKeystroke(Keys.right(), { }), sAssertCursor(tinyApis, [0, 1, 0], 1), sAssertContentStructure(editor, anchorSurroundedWithZwspInside(END)), tinyActions.sContentKeystroke(Keys.right(), { }), sAssertCursor(tinyApis, [0, 2], 1), sAssertContentStructure(editor, anchorSurroundedWithZwspOutside(AFTER)) ])); };
(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); },
return Arr.bind(navigation.concat(navigation.slice(0, 1)), (nav, i) => { const exploration = (nav.subitems.length > 0) ? [ Keyboard.sKeydown(doc, Keys.right(), { }), sAssertFocusOnItem(doc, nav.subitems[0]) ].concat( Arr.bind( nav.subitems.slice(1).concat(nav.subitems.slice(0, 1)), (si) => [ Keyboard.sKeydown(doc, Keys.down(), { }), sDelay, sAssertFocusOnItem(doc, si) ] ) ).concat([ Keyboard.sKeydown(doc, Keys.escape(), { }) ]) : [ // Should do nothing Keyboard.sKeydown(doc, Keys.right(), { }) ]; return Arr.flatten([ [ sAssertFocusOnItem(doc, nav.item) ], exploration, [ sAssertFocusOnItem(doc, nav.item) ], [ sDelay ], // Move to the next one i < navigation.length ? [ Keyboard.sKeydown(doc, Keys.down(), { }) ] : [ ] ]); });
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const tinyActions = TinyActions(editor); Pipeline.async({}, [ tinyApis.sFocus, Logger.t('ul > li in table', GeneralSteps.sequence([ tinyApis.sSetContent('<table><tbody><tr><td><ul><li>a</li><li>b</li></ul></td></tr></tbody></table>'), tinyApis.sSetCursor([0, 0, 0, 0, 0, 1], 1), tinyActions.sContentKeystroke(Keys.tab(), {}), sAssertTableInnerHTML(editor, '<tbody><tr><td><ul><li>a<ul><li>b</li></ul></li></ul></td></tr></tbody>') ])), Logger.t('ol > li in table', GeneralSteps.sequence([ tinyApis.sSetContent('<table><tbody><tr><td><ol><li>a</li><li>b</li></ol></td></tr></tbody></table>'), tinyApis.sSetCursor([0, 0, 0, 0, 0, 1], 1), tinyActions.sContentKeystroke(Keys.tab(), {}), sAssertTableInnerHTML(editor, '<tbody><tr><td><ol><li>a<ol><li>b</li></ol></li></ol></td></tr></tbody>') ])), Logger.t('dl > dt in table', GeneralSteps.sequence([ tinyApis.sSetContent('<table><tbody><tr><td><dl><dt>a</dt><dt>b</dt></dl></td></tr></tbody></table>'), tinyApis.sSetCursor([0, 0, 0, 0, 0, 1], 1), tinyActions.sContentKeystroke(Keys.tab(), {}), sAssertTableInnerHTML(editor, '<tbody><tr><td><dl><dt>a</dt><dd>b</dd></dl></td></tr></tbody>') ])) ], onSuccess, onFailure); }, {
TinyLoader.setup(function (editor, onSuccess, onFailure) { const tinyApis = TinyApis(editor); const doc = TinyDom.fromDom(document); Pipeline.async({}, [ Log.stepsAsStep('TBA', 'Link: should not get anchor info if not selected node', [ TestLinkUi.sClearHistory, tinyApis.sSetContent('<p><a href="http://tinymce.com" class="shouldbekept" title="shouldalsobekept">tiny</a></p>'), tinyApis.sSetSelection([0, 0, 0], 2, [0, 0, 0], 2), tinyApis.sExecCommand('mcelink'), TestLinkUi.sAssertDialogContents({ href: 'http://tinymce.com', text: 'tiny', title: 'shouldalsobekept', target: '' }), FocusTools.sSetActiveValue(doc, 'http://something'), Keyboard.sKeydown(doc, Keys.enter(), { }), Waiter.sTryUntil( 'Wait until link is inserted', tinyApis.sAssertContentPresence({ 'a[href="http://something"]': 1, 'a[class="shouldbekept"]': 1, 'a[title="shouldalsobekept"]': 1 }), 100, 1000 ), TestLinkUi.sClearHistory ]), Log.stepsAsStep('TBA', 'Link: should remove attributes if unset in the dialog', [ TestLinkUi.sClearHistory, tinyApis.sSetContent('<p><a href="http://tinymce.com" class="shouldbekept" title="shouldnotbekept">tiny</a></p>'), tinyApis.sSetSelection([0, 0, 0], 2, [0, 0, 0], 2), tinyApis.sExecCommand('mcelink'), TestLinkUi.sAssertDialogContents({ href: 'http://tinymce.com', text: 'tiny', title: 'shouldnotbekept', target: '' }), FocusTools.sSetActiveValue(doc, 'http://something'), TestLinkUi.sSetInputFieldValue('Title', ''), Keyboard.sKeydown(doc, Keys.enter(), { }), Waiter.sTryUntil( 'Wait until link is inserted', tinyApis.sAssertContentPresence({ 'a[href="http://something"]': 1, 'a[class="shouldbekept"]': 1, 'a[title="shouldnotbekept"]': 0 }), 100, 1000 ), TestLinkUi.sClearHistory ]) ], onSuccess, onFailure); }, {
TinyLoader.setup((editor, onSuccess, onFailure) => { const tinyApis = TinyApis(editor); const doc = Element.fromDom(document); // Tab key press const sPressTabKey = Keyboard.sKeydown(doc, Keys.tab(), { }); // Down arrow key press to nav between tabs const sPressDownArrowKey = Keyboard.sKeydown(doc, Keys.down(), { }); // Assert focus is on the expected form element const sAssertFocusOnItem = (label, selector) => { return FocusTools.sTryOnSelector( `Focus should be on: ${label}`, doc, selector ); }; Pipeline.async({}, [ Log.stepsAsStep('TBA', 'Help: Open dialog', [ tinyApis.sFocus, tinyApis.sExecCommand('mceHelp') ]), Log.stepsAsStep('TBA', 'Help: test the tab key navigation cycles through all focusable fields in Handy Shortcuts tab', [ sAssertFocusOnItem('Handy Shortcuts Tab', '.tox-dialog__body-nav-item:contains("Handy Shortcuts")'), sPressTabKey, sAssertFocusOnItem('Handy Shortcuts Items', '.tox-dialog__table'), sPressTabKey, sAssertFocusOnItem('Close Button', '.tox-button:contains("Close")'), sPressTabKey, sAssertFocusOnItem('Handy Shortcuts Tab', '.tox-dialog__body-nav-item:contains("Handy Shortcuts")'), sPressDownArrowKey ]), Log.stepsAsStep('TBA', 'Help: test the tab key navigation cycles through all focusable fields in Plugins tab', [ sAssertFocusOnItem('Plugins Tab', '.tox-dialog__body-nav-item:contains("Plugins")'), sPressTabKey, sAssertFocusOnItem('Installed Plugins', 'div[role="document"]'), sPressTabKey, sAssertFocusOnItem('Close Button', '.tox-button:contains("Close")'), sPressTabKey, sAssertFocusOnItem('Plugins Tab', '.tox-dialog__body-nav-item:contains("Plugins")'), sPressDownArrowKey ]), Log.stepsAsStep('TBA', 'Help: test the tab key navigation cycles through all focusable fields in Version tab', [ sAssertFocusOnItem('Version Tab', '.tox-dialog__body-nav-item:contains("Version")'), sPressTabKey, sAssertFocusOnItem('TinyMCE Version', 'div[role="document"]'), sPressTabKey, sAssertFocusOnItem('Close Button', '.tox-button:contains("Close")'), sPressTabKey, sAssertFocusOnItem('Version Tab', '.tox-dialog__body-nav-item:contains("Version")') ]) ], onSuccess, onFailure); }, {
(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); },
const sCheckSubItemsAtLocation = (expectedSubmenu: string) => sCheckItemsAtLocationPlus( GeneralSteps.sequence([ Keyboard.sKeydown(doc, Keys.right(), { }), sAssertFocusOnItem(expectedSubmenu) ]), // Afterwards, escape the submenu Keyboard.sKeydown(doc, Keys.escape(), { }), (text) => sOpenMenu('', text) );