TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('Insert contents on a triple click selection should not produce odd spans', GeneralSteps.sequence([
        tinyApis.sSetContent('<blockquote><p>a</p></blockquote><p>b</p>'),
        tinyApis.sSetSelection([0, 0, 0], 0, [1], 0),
        tinyApis.sExecCommand('mceInsertContent', '<p>c</p>'),
        tinyApis.sAssertContent('<blockquote><p>c</p></blockquote><p>b</p>'),
        tinyApis.sAssertSelection([0, 0, 0], 1, [0, 0, 0], 1)
      ]))
    ], onSuccess, onFailure);
  }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('Tests if the editor is responsive after setting theme to false', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p>'),
        tinyApis.sAssertContent('<p>a</p>')
      ])),
      Logger.t('Editor element properties', Step.sync(function () {
        const body = Element.fromDom(document.body);
        const targetElement = SelectorFind.descendant(body, '#' + editor.id).getOrDie('No elm');
        const nextElement = Traverse.nextSibling(targetElement);

        // TODO FIXME this seems like an odd exception
        Assertions.assertEq('Should be null since inline without a theme does not set editorContainer', null, editor.editorContainer);
        Assertions.assertDomEq('Should be expected editor body element', targetElement, Element.fromDom(editor.getBody()));
        Assertions.assertDomEq('Should be expected editor target element', targetElement, Element.fromDom(editor.getElement()));
        Assertions.assertDomEq('Editor.contentAreaContainer should equal target element', targetElement, Element.fromDom(editor.contentAreaContainer));
        Assertions.assertEq('Should be no element after target', true, nextElement.isNone());
      }))
    ], onSuccess, onFailure);
  }, {
  TinyLoader.setup(function (editor: Editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, Env.gecko ? [ // This test is only relevant on Firefox
      Logger.t('cursor before table type', GeneralSteps.sequence([
        tinyApis.sSetContent('<table style="border-collapse: collapse; width: 100%;" border="1"><tbody><tr><td style="width: 50%;">&nbsp;</td><td style="width: 50%;">&nbsp;</td></tr><tr><td style="width: 50%;">&nbsp;</td><td style="width: 50%;">&nbsp;</td></tr></tbody></table>'),
        tinyApis.sSetCursor([], 0),
        sAssertUndoManagerDataLength(editor, 1),
        Step.sync(() => KeyUtils.type(editor, 'a')),
        sAssertUndoManagerDataLength(editor, 3)
      ]))
    ] : [], onSuccess, onFailure);
  }, {
    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      const tinyApis = TinyApis(editor);
      const tinyActions = TinyActions(editor);

      Pipeline.async({}, [
        Logger.t('Undo level on insert tab', GeneralSteps.sequence([
          tinyActions.sContentKeystroke(Keys.tab(), {}),
          tinyApis.sAssertContent('<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>'),
          Step.sync(function () {
            editor.undoManager.undo();
          }),
          tinyApis.sAssertContent('')
        ])),
        Logger.t('Prevent default and other handlers on insert tab', GeneralSteps.sequence([
          Step.sync(function () {
            const args = editor.fire('keydown', { keyCode: VK.TAB });
            RawAssertions.assertEq('Default should be prevented', true, args.isDefaultPrevented());
            RawAssertions.assertEq('Should not propagate', true, args.isImmediatePropagationStopped());
          })
        ]))
      ], onSuccess, onFailure);
    }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, Arr.flatten([
      [
        Logger.t('Fullscreen toggle scroll state', GeneralSteps.sequence([
          tinyApis.sExecCommand('mceFullScreen'),
          sAssertScroll(editor, true),
          tinyApis.sExecCommand('mceFullScreen'),
          sAssertScroll(editor, false)
        ])),
        Logger.t('Editor size increase based on content size', GeneralSteps.sequence([
          tinyApis.sSetContent('<div style="height: 5000px;">a</div>'),
          Waiter.sTryUntil('wait for editor height', sAssertEditorHeightAbove(editor, 5000), 10, 3000)
        ])),
        Logger.t('Editor size decrease based on content size', GeneralSteps.sequence([
          tinyApis.sSetContent('<div style="height: 1000px;">a</div>'),
          Waiter.sTryUntil('wait for editor height', sAssertEditorHeightBelow(editor, 2000), 10, 3000)
        ]))
      ],

      // These tests doesn't work on phantom since measuring things seems broken there
      navigator.userAgent.indexOf('PhantomJS') === -1 ? [
        Logger.t('Editor size decrease content to 1000 based and restrict by max height', GeneralSteps.sequence([
          tinyApis.sSetSetting('autoresize_max_height', 200),
          tinyApis.sSetContent('<div style="height: 1000px;">a</div>'),
          Waiter.sTryUntil('wait for editor height', sAssertEditorHeightBelow(editor, 500), 10, 3000),
          tinyApis.sSetSetting('autoresize_max_height', 0)
        ])),
        Logger.t('Editor size decrease content to 10 and set min height to 500', GeneralSteps.sequence([
          tinyApis.sSetSetting('autoresize_min_height', 500),
          tinyApis.sSetContent('<div style="height: 10px;">a</div>'),
          Waiter.sTryUntil('wait for editor height', sAssertEditorHeightAbove(editor, 300), 10, 3000),
          tinyApis.sSetSetting('autoresize_min_height', 0)
        ]))
      ] : []
    ]), onSuccess, onFailure);
  }, {
    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      const tinyApis = TinyApis(editor);
      const tinyActions = TinyActions(editor);

      Pipeline.async({}, [
        tinyApis.sFocus,
        Logger.t('Arrow keys in figcaption', GeneralSteps.sequence([
          Logger.t('Arrow up from start of figcaption to paragraph before figure', GeneralSteps.sequence([
            tinyApis.sSetContent('<figure><figcaption>a</figcaption></figure>'),
            tinyApis.sSetCursor([0, 0, 0], 0),
            tinyActions.sContentKeystroke(Keys.up(), { }),
            tinyApis.sAssertContent('<br /><figure><figcaption>a</figcaption></figure>'),
            tinyApis.sAssertSelection([], 0, [], 0)
          ])),
          Logger.t('Arrow down from end of figcaption to paragraph after figure', GeneralSteps.sequence([
            tinyApis.sSetContent('<figure><figcaption>a</figcaption></figure>'),
            tinyApis.sSetCursor([0, 0, 0], 1),
            tinyActions.sContentKeystroke(Keys.down(), { }),
            sAssertRawContent(editor, '<figure><figcaption>a</figcaption></figure><br>'),
            tinyApis.sAssertSelection([], 1, [], 1)
          ])),
          Logger.t('Arrow up in middle of figcaption', GeneralSteps.sequence([
            tinyApis.sSetContent('<figure><figcaption>ab</figcaption></figure>'),
            tinyApis.sSetCursor([0, 0, 0], 1),
            tinyActions.sContentKeystroke(Keys.up(), { }),
            sAssertRawContent(editor, '<br><figure><figcaption>ab</figcaption></figure>'),
            tinyApis.sAssertSelection([], 0, [], 0)
          ])),
          Logger.t('Arrow down in middle of figcaption', GeneralSteps.sequence([
            tinyApis.sSetContent('<figure><figcaption>ab</figcaption></figure>'),
            tinyApis.sSetCursor([0, 0, 0], 1),
            tinyActions.sContentKeystroke(Keys.down(), { }),
            sAssertRawContent(editor, '<figure><figcaption>ab</figcaption></figure><br>'),
            tinyApis.sAssertSelection([], 1, [], 1)
          ]))
        ]))
      ], onSuccess, onFailure);
    }, {
Example #7
0
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('test generate filename', GeneralSteps.sequence([
        uploadHandlerState.sResetState,
        tinyApis.sSetSetting('images_reuse_filename', false),
        ImageUtils.sLoadImage(editor, srcUrl),
        tinyApis.sSelect('img', []),
        ImageUtils.sExecCommand(editor, 'mceImageFlipHorizontal'),
        ImageUtils.sWaitForBlobImage(editor),
        ImageUtils.sUploadImages(editor),
        uploadHandlerState.sWaitForState,
        sAssertUploadFilename('imagetools0.jpg')
      ])),
      Logger.t('test reuse filename', GeneralSteps.sequence([
        uploadHandlerState.sResetState,
        tinyApis.sSetSetting('images_reuse_filename', true),
        ImageUtils.sLoadImage(editor, srcUrl),
        tinyApis.sSelect('img', []),
        ImageUtils.sExecCommand(editor, 'mceImageFlipHorizontal'),
        ImageUtils.sWaitForBlobImage(editor),
        ImageUtils.sUploadImages(editor),
        uploadHandlerState.sWaitForState,
        sAssertUploadFilename('dogleft.jpg'),
        sAssertUri(srcUrl)
      ])),
      Logger.t('test rotate image', GeneralSteps.sequence([
        ImageUtils.sLoadImage(editor, srcUrl, {width: 200, height: 100}),
        tinyApis.sSelect('img', []),
        ImageUtils.sExecCommand(editor, 'mceImageRotateRight'),
        ImageUtils.sWaitForBlobImage(editor),
        tinyApis.sAssertContentPresence({
          'img[width="100"][height="200"]': 1
        })
      ]))
    ], onSuccess, onFailure);
  }, {
Example #8
0
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyActions = TinyActions(editor);

    Pipeline.async({}, [
      tinyApis.sFocus,

      Logger.t('Enter before HR in the beginning of content', GeneralSteps.sequence([
        tinyApis.sSetContent('<hr /><p>a</p>'),
        tinyApis.sSetCursor([], 0),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<p>&nbsp;</p><hr /><p>a</p>'),
        tinyApis.sAssertSelection([0], 0, [0], 0)
      ])),

      Logger.t('Enter after HR in the beginning of content', GeneralSteps.sequence([
        tinyApis.sSetContent('<hr /><p>a</p>'),
        tinyApis.sSetCursor([], 1),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<hr /><p>&nbsp;</p><p>a</p>'),
        tinyApis.sAssertSelection([2, 0], 0, [2, 0], 0)
      ])),

      Logger.t('Enter before HR in the middle of content', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p><hr /><p>b</p>'),
        tinyApis.sSetCursor([], 1),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<p>a</p><p>&nbsp;</p><hr /><p>b</p>'),
        tinyApis.sAssertSelection([1], 0, [1], 0)
      ])),

      Logger.t('Enter after HR in the middle of content', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p><hr /><p>b</p>'),
        tinyApis.sSetCursor([], 2),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<p>a</p><hr /><p>&nbsp;</p><p>b</p>'),
        tinyApis.sAssertSelection([3, 0], 0, [3, 0], 0)
      ])),

      Logger.t('Enter before HR in the end of content', GeneralSteps.sequence([
        tinyApis.sFocus,
        tinyApis.sSetContent('<p>a</p><hr />'),
        tinyApis.sSetCursor([], 1),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<p>a</p><p>&nbsp;</p><hr />'),
        tinyApis.sAssertSelection([1], 0, [1], 0)
      ])),

      Logger.t('Enter after HR in the end of content', GeneralSteps.sequence([
        tinyApis.sFocus,
        tinyApis.sSetContent('<p>a</p><hr />'),
        tinyApis.sSetCursor([], 2),
        tinyActions.sContentKeystroke(Keys.enter(), {}),
        tinyApis.sAssertContent('<p>a</p><hr /><p>&nbsp;</p>'),
        tinyApis.sAssertSelection([2], 0, [2], 0)
      ]))
    ], onSuccess, onFailure);
  }, {
Example #9
0
    TinyLoader.setup(function (editor, onSuccess, onFailure) {

      editor.on('execCommand', function (e) {
        state.set(e.command);
      });

      const tinyUi = TinyUi(editor);
      const tinyApis = TinyApis(editor);

      Pipeline.async({}, browser.isIE() ? [] : [
        Logger.t('apply and remove forecolor and make sure of the right command has been executed', GeneralSteps.sequence([
          tinyApis.sFocus,
          tinyApis.sSetContent('hello test'),
          tinyApis.sSetSelection([0, 0], 0, [0, 0], 5),
          tinyUi.sClickOnToolbar('click forecolor', 'div[aria-label="Text color"] > button.mce-open'),
          tinyUi.sClickOnUi('click green color', 'div[data-mce-color="#00FF00"]:first'),
          sAssertState('mceApplyTextcolor'),
          tinyApis.sSetSelection([0, 0, 0], 0, [0, 0, 0], 5),
          tinyUi.sClickOnToolbar('click forecolor', 'div[aria-label="Text color"] > button.mce-open'),
          tinyUi.sClickOnUi('click green color', 'div[data-mce-color="transparent"]:first'),
          sAssertState('mceRemoveTextcolor'),
          sResetState
        ])),
        Logger.t('apply and remove forecolor and make sure of the right command has been executed', GeneralSteps.sequence([
          tinyApis.sFocus,
          tinyApis.sSetContent('hello test'),
          tinyApis.sSetSelection([0, 0], 0, [0, 0], 5),
          tinyUi.sClickOnToolbar('click backcolor', 'div[aria-label="Background color"] > button.mce-open'),
          tinyUi.sClickOnUi('click green color', 'div[data-mce-color="#00FF00"]:last'),
          sAssertState('mceApplyTextcolor'),
          tinyApis.sSetSelection([0, 0, 0], 0, [0, 0, 0], 5),
          tinyUi.sClickOnToolbar('click backcolor', 'div[aria-label="Background color"] > button.mce-open'),
          tinyUi.sClickOnUi('click green color', 'div[data-mce-color="transparent"]:first'),
          sAssertState('mceRemoveTextcolor'),
          sResetState
        ]))
      ], onSuccess, onFailure);
    }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('isXYInContentArea without borders, margin', GeneralSteps.sequence([
        sSetBodyStyles(editor, { border: '0', margin: '0', width: '100px', height: '100px', overflow: 'scroll' }),
        tinyApis.sSetContent('<div style="width: 5000px; height: 5000px">X</div>'),
        sTestIsXYInContentArea(editor, 0, 0)
      ])),

      Logger.t('isXYInContentArea with margin', GeneralSteps.sequence([
        sSetBodyStyles(editor, { margin: '15px' }),
        tinyApis.sSetContent('<div style="width: 5000px; height: 5000px">X</div>'),
        sTestIsXYInContentArea(editor, -15, -15)
      ])),

      Logger.t('isXYInContentArea with borders, margin', GeneralSteps.sequence([
        sSetBodyStyles(editor, { border: '5px', margin: '15px' }),
        tinyApis.sSetContent('<div style="width: 5000px; height: 5000px">X</div>'),
        sTestIsXYInContentArea(editor, -20, -20)
      ]))
    ], onSuccess, onFailure);
  }, {
    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      const tinyApis = TinyApis(editor);
      const tinyActions = TinyActions(editor);

      Pipeline.async({}, [
        Logger.t('test table grid disabled', GeneralSteps.sequence([
          tinyApis.sFocus,
          tinyApis.sSetContent(tableHtml),
          TableTestUtils.sOpenToolbarOn(editor, 'td', [0]),
          tinyActions.sContentKeystroke(Keys.tab(), {}),
          tinyApis.sAssertSelection([0, 0, 0, 0], 0, [0, 0, 0, 0], 1)
        ]))
      ], onSuccess, onFailure);
    }, {
Example #12
0
const sSetInputValue = (label, selector, value) => {
  return Logger.t(label,
    Chain.asStep({}, [
      cGetInput(selector),
      Chain.op((element) => {
        if (element.dom().type === 'checkbox') {
          element.dom().checked = value;
          return;
        }
        Value.set(element, value);
      })
    ]),
  );
};
Example #13
0
 const sAssertColour = (label: string, expected: string, labelText: string) =>
   Logger.t(
     label,
     Waiter.sTryUntil(
       'Waiting until hex updates the other fields',
       Chain.asStep(component.element(), [
         UiFinder.cFindIn(`label:contains("${labelText}") + input`),
         UiControls.cGetValue,
         Assertions.cAssertEq('Checking value in input', expected)
       ]),
       100,
       1000
     )
   );
Example #14
0
const sAssertInputValue = (label, selector, expected) => {
  return Logger.t(label,
    Chain.asStep({}, [
      cGetInput(selector),
      Chain.op((element) => {
        if (element.dom().type === 'checkbox') {
          Assertions.assertEq(`The input value for ${label} should be: `, expected, element.dom().checked);
          return;
        }
        Assertions.assertEq(`The input value for ${label} should be: `, expected, Value.get(element));
      })
    ]),
  );
};
Example #15
0
 const sAssertImageTab = function (title, isPresent) {
   return Logger.t('Assert image tab is present', GeneralSteps.sequence([
     ui.sClickOnToolbar('Trigger Image dialog', 'button[aria-label="Insert/edit image"]'),
     Chain.asStep({}, [
       ui.cWaitForPopup('Wait for Image dialog', 'div[role="dialog"]'),
       Chain.op(function (container) {
         const expected = {};
         expected['.tox-tab:contains("' + title + '")'] = isPresent ? 1 : 0;
         Assertions.assertPresence('Asserting presence', expected, container);
       })
     ]),
     ui.sClickOnUi('Close dialog', 'button:contains("Cancel")')
   ]));
 };
Example #16
0
 const sParseStyles = function (editor) {
   return Logger.t('Parse styles', GeneralSteps.sequence([
     Step.sync(function () {
       editor.setContent('<html><head><style>p {text-transform: uppercase}</style></head><body dir="rtl"><p>Test</p></body></html>');
     }),
     Waiter.sTryUntil(
       'Expected styles were added',
       Step.sync(function () {
         Assertions.assertEq('Styles added to iframe document', 'uppercase', editor.dom.getStyle(editor.getBody().firstChild, 'text-transform', true));
         Assertions.assertEq('Styles not added to actual element', '', editor.dom.getStyle(editor.getBody().firstChild, 'text-transform', false));
       }
     ), 10, 3000)
   ]));
 };
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyUi = TinyUi(editor);

    Pipeline.async({}, [
      Logger.t('toggle bullet list on list with two empty LIs', GeneralSteps.sequence([
        tinyApis.sFocus,
        tinyApis.sSetContent('<ul><li>a</li><li>&nbsp;</li><li>&nbsp;</li><li>b</li></ul>'),
        tinyApis.sSetSelection([0, 0, 0], 0, [0, 3, 0], 1),
        tinyUi.sClickOnToolbar('click list', 'div[aria-label="Bullet list"] > button'),
        tinyApis.sAssertContent('<p>a</p><p>&nbsp;</p><p>&nbsp;</p><p>b</p>')
      ])),
    ], onSuccess, onFailure);
  }, {
Example #18
0
 TinyLoader.setup(function (editor, onSuccess, onFailure) {
   Pipeline.async({}, [
     Logger.t('Should toggle readonly on/off and have a readonly class', GeneralSteps.sequence([
       sAssertMode(editor, EditorMode.ReadOnly),
       sAssertBodyClass(editor, 'mce-content-readonly', true),
       sSetMode(editor, EditorMode.Design),
       sAssertMode(editor, EditorMode.Design),
       sAssertBodyClass(editor, 'mce-content-readonly', false),
       sSetMode(editor, EditorMode.ReadOnly),
       sAssertMode(editor, EditorMode.ReadOnly),
       sAssertBodyClass(editor, 'mce-content-readonly', true)
     ]))
   ], onSuccess, onFailure);
 }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      tinyApis.sFocus,
      Logger.t('Click on content editable false', GeneralSteps.sequence([
        tinyApis.sSetContent('<p contenteditable="false">a</p>'),
        sClickMiddleOf(editor, [0]),
        tinyApis.sAssertSelection([], 0, [], 1)
      ])),
      Logger.t('Click on content editable false inside content editable true', GeneralSteps.sequence([
        tinyApis.sSetContent('<div contenteditable="true"><p contenteditable="false">a</p></div>'),
        sClickMiddleOf(editor, [0, 0]),
        tinyApis.sAssertSelection([0], 0, [0], 1)
      ])),
      Logger.t('Click on content editable true inside content editable false', GeneralSteps.sequence([
        tinyApis.sSetContent('<div contenteditable="false"><p contenteditable="true">a</p></div>'),
        sClickMiddleOf(editor, [0, 0]),
        tinyApis.sAssertSelection([0, 0, 0], 1, [0, 0, 0], 1)
      ])),
      Logger.t('Click on content editable false inside content editable true and then on content editable true and type', GeneralSteps.sequence([
        tinyApis.sSetContent('<div contenteditable="true"><p contenteditable="false">a</p><p>b</p></div>'),
        sClickMiddleOf(editor, [0, 0]),
        sClickMiddleOf(editor, [0, 1]),
        tinyApis.sAssertSelection([0, 1, 0], 1, [0, 1, 0], 1),
        TypeText.sTypeContentAtSelection(Element.fromDom(editor.getDoc()), 'c'),
        tinyApis.sAssertContent('<div contenteditable="true"><p contenteditable="false">a</p><p>bc</p></div>'),
        tinyApis.sAssertSelection([0, 1, 0], 2, [0, 1, 0], 2)
      ])),
      Logger.t('Click on content editable false then outside on content editable inherit', GeneralSteps.sequence([
        tinyApis.sSetContent('<p contenteditable="false">a</p><p>a</p>'),
        sClickMiddleOf(editor, [0]),
        sClickMiddleOf(editor, [1]),
        tinyApis.sAssertSelection([1, 0], 1, [1, 0], 1)
      ]))
    ], 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', [0]),
        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', [0]),
        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>')
      ]))
    ], onSuccess, onFailure);
  }, {
Example #21
0
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyActions = TinyActions(editor);

    Pipeline.async({}, [
      tinyApis.sFocus,

      Log.stepsAsStep('TBA', 'Delete keys for image block element', [
        Logger.t('Should place the selection on the image block element on delete before', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a<img src="about:blank" class="block">b</p>'),
          tinyApis.sSetSelection([0, 0], 1, [0, 0], 1),
          tinyActions.sContentKeystroke(VK.DELETE, {}),
          tinyApis.sAssertSelection([0], 1, [0], 2)
        ])),

        Logger.t('Should place the selection on the image block element on delete before', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a</p><p><img src="about:blank" class="block"></p><p>b</p>'),
          tinyApis.sSetSelection([0, 0], 1, [0, 0], 1),
          tinyActions.sContentKeystroke(VK.DELETE, {}),
          tinyApis.sAssertSelection([1], 0, [1], 1)
        ]))
      ]),

      Log.stepsAsStep('TBA', 'Backspace keys for image block element', [
        Logger.t('Should place the selection on the image block element on backspace after', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a<img src="about:blank" class="block">b</p>'),
          tinyApis.sSetSelection([0, 2], 0, [0, 2], 0),
          tinyActions.sContentKeystroke(Keys.backspace(), {}),
          tinyApis.sAssertSelection([0], 1, [0], 2)
        ])),

        Logger.t('Should place the selection on the image block element on backspace after', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a</p><p><img src="about:blank" class="block"></p><p>b</p>'),
          tinyApis.sSetSelection([2, 0], 0, [2, 0], 0),
          tinyActions.sContentKeystroke(Keys.backspace(), {}),
          tinyApis.sAssertSelection([1], 0, [1], 1)
        ]))
      ]),

      Log.stepsAsStep('TBA', 'Backspace/delete before on non block images should not select the image', [
        Logger.t('Should place the selection on the image block element on backspace after', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a<img src="about:blank">b</p>'),
          tinyApis.sSetSelection([0, 0], 1, [0, 0], 1),
          tinyActions.sContentKeystroke(VK.DELETE, {}),
          tinyApis.sAssertSelection([0, 0], 1, [0, 0], 1)
        ])),

        Logger.t('Should place the selection on the image block element on backspace after', GeneralSteps.sequence([
          tinyApis.sSetContent('<p>a<img src="about:blank">b</p>'),
          tinyApis.sSetSelection([0, 2], 0, [0, 2], 0),
          tinyActions.sContentKeystroke(Keys.backspace(), {}),
          tinyApis.sAssertSelection([0, 2], 0, [0, 2], 0)
        ]))
      ])
    ], onSuccess, onFailure);
  }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyUi = TinyUi(editor);
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('Context menu click on text', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a</p>'),
        tinyApis.sSetSelection([0, 0], 0, [0, 0], 1),
        Mouse.sContextMenuOn(Element.fromDom(editor.getBody()), 'p'),
        tinyUi.sWaitForUi('wait for context', 'div.mce-contextmenu'),
        tinyUi.sClickOnUi('click on link in context', 'div.mce-contextmenu span:contains("Bold")'),
        tinyApis.sAssertContentStructure(ApproxStructure.build(function (s, str) {
          return s.element('body', {
            children: [
              s.element('p', {
                children: [
                  s.element('strong', {
                    children: [
                      s.text(str.is('a'))
                    ]
                  })
                ]
              })
            ]
          });
        }))
      ])),

      Logger.t('Do not select image if the context menu click is inside the currently selected range', GeneralSteps.sequence([
        tinyApis.sSetContent('<p>a<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==" width="100" height="100"></p>'),
        tinyApis.sSetSelection([0, 0], 0, [0], 2),
        sContextMenuClickInMiddleOf(editor, [0, 1]),
        tinyApis.sAssertSelection([0, 0], 0, [0], 2)
      ]))
    ], onSuccess, onFailure);
  }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('Insert table 2x2', GeneralSteps.sequence([
        tinyApis.sSetContent(''),
        sInsertTable(editor, 2, 2),
        tinyApis.sAssertContent('<table style="width: 100%; border-collapse: collapse;" border="1"><tbody><tr><td style="width: 50%;">&nbsp;</td><td style="width: 50%;">&nbsp;</td></tr><tr><td style="width: 50%;">&nbsp;</td><td style="width: 50%;">&nbsp;</td></tr></tbody></table>'),
        tinyApis.sAssertSelection([0, 0, 0, 0], 0, [0, 0, 0, 0], 0)
      ])),
      Logger.t('Insert table 1x2', GeneralSteps.sequence([
        tinyApis.sSetContent(''),
        sInsertTable(editor, 1, 2),
        tinyApis.sAssertContent('<table style="width: 100%; border-collapse: collapse;" border="1"><tbody><tr><td style="width: 100%;">&nbsp;</td></tr><tr><td style="width: 100%;">&nbsp;</td></tr></tbody></table>'),
        tinyApis.sAssertSelection([0, 0, 0, 0], 0, [0, 0, 0, 0], 0)
      ])),
      Logger.t('Insert table 2x1', GeneralSteps.sequence([
        tinyApis.sSetContent(''),
        sInsertTable(editor, 2, 1),
        tinyApis.sAssertContent('<table style="width: 100%; border-collapse: collapse;" border="1"><tbody><tr><td style="width: 50%;">&nbsp;</td><td style="width: 50%;">&nbsp;</td></tr></tbody></table>'),
        tinyApis.sAssertSelection([0, 0, 0, 0], 0, [0, 0, 0, 0], 0)
      ]))
    ], onSuccess, onFailure);
  }, {
Example #24
0
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyActions = TinyActions(editor);

    const steps = Utils.withTeardown([
      Logger.t('inline italic then undo', GeneralSteps.sequence([
        Utils.sSetContentAndPressSpace(tinyApis, tinyActions, '*a*'),
        tinyApis.sAssertContentStructure(Utils.inlineStructHelper('em', 'a')),
        tinyApis.sExecCommand('Undo'),
        tinyApis.sAssertContent('<p>*a*&nbsp;</p>')
      ]))
    ], tinyApis.sSetContent(''));

    Pipeline.async({}, steps, onSuccess, onFailure);
  }, {
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const steps = Env.ie ? [] : [
      tinyApis.sFocus,
      Logger.t('Chrome adds a nbsp between link and text', GeneralSteps.sequence([
        tinyApis.sSetContent('<p><a href="http://www.domain.com">www.domain.com</a>&nbsp;www.domain.com</p>'),
        tinyApis.sSetCursor([0, 1], 15),
        Step.sync(function () {
          KeyUtils.type(editor, ' ');
        }),
        tinyApis.sAssertContent('<p><a href="http://www.domain.com">www.domain.com</a>&nbsp;<a href="http://www.domain.com">www.domain.com</a>&nbsp;</p>')
      ])),
      Logger.t('FireFox does not seem to add a nbsp between link and text', GeneralSteps.sequence([
        tinyApis.sSetContent('<p><a href="http://www.domain.com">www.domain.com</a> www.domain.com</p>'),
        tinyApis.sSetCursor([0, 1], 15),
        Step.sync(function () {
          KeyUtils.type(editor, ' ');
        }),
        tinyApis.sAssertContent('<p><a href="http://www.domain.com">www.domain.com</a> <a href="http://www.domain.com">www.domain.com</a>&nbsp;</p>')
      ]))
    ];

    Pipeline.async({}, steps, onSuccess, onFailure);
  }, {
Example #26
0
 const createTest = (label, conf, asserter) => Logger.t(
   label,
   GeneralSteps.sequence([
     Waiter.sTryUntil(
       'Waiting for any other dialogs to disappear',
       UiFinder.sNotExists(Body.body(), '.tox-button--icon[aria-label="Close"]'),
       100,
       1000
     ),
     sSetupDialog(conf),
     UiFinder.sWaitFor('Waiting for dialog to appear', Body.body(), '.tox-button--icon[aria-label="Close"]'),
     sAssertSinkStructure(asserter),
     sTeardown,
   ])
 );
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);

    Pipeline.async({}, [
      Logger.t('test that table toolbar can be disabled', GeneralSteps.sequence([
        tinyApis.sFocus,
        tinyApis.sSetSetting('table_toolbar', 'tableprops tabledelete'),
        tinyApis.sSetContent(tableHtml),
        tinyApis.sSetSelection([0, 0, 0, 0, 0], 0, [0, 0, 0, 0, 0], 1),
        Step.wait(100), // How should I do this better?
                        // I want to check that the inline toolbar does not appear,
                        // but I have to wait unless it won't exist any way because it's too fast
        UiFinder.sNotExists(TinyDom.fromDom(document.body), 'div[aria-label="Inline toolbar"]')
      ]))
    ], onSuccess, onFailure);
  }, {
Example #28
0
 const sDragDropBlocker = (container, selector, dx, dy) => {
   return Logger.t('Block dragging and dropping of any other element in the container', Chain.asStep({}, [
     Chain.fromParent(Chain.inject(container), [
       Chain.fromChains([
         UiFinder.cFindIn(selector),
         Mouse.cMouseDown
       ]),
       Chain.fromChains([
         UiFinder.cFindIn('div.ephox-dragster-blocker'),
         Mouse.cMouseMove,
         Mouse.cMouseMoveTo(dx, dy),
         Mouse.cMouseUpTo(dx, dy)
       ])
     ])
   ]));
 };
  TinyLoader.setup(function (editor, onSuccess, onFailure) {
    const tinyApis = TinyApis(editor);
    const tinyActions = TinyActions(editor);
    const sTestBackspace = sTestDeleteOrBackspaceKey(editor, tinyApis, tinyActions, Keys.backspace());
    const sTestDelete = sTestDeleteOrBackspaceKey(editor, tinyApis, tinyActions, 46);

    Pipeline.async({}, [
      tinyApis.sFocus,
      Logger.t('Backspace key on text', GeneralSteps.sequence([
        sTestBackspace('<p>a<a href="#">b</a>c</p>', [0, 2], 0, '<p>a<a href="#">b</a>c</p>', 'end', [0, 1, 0], 1),
        sTestBackspace('<p>a<a href="#">b</a>c</p>', [0, 1, 0], 0, '<p>a<a href="#">b</a>c</p>', 'before', [0, 0], 1),
        sTestBackspace('<p>a<a href="#">bc</a>d</p>', [0, 1, 0], 1, '<p>a<a href="#">c</a>d</p>', 'start', [0, 1, 0], 1)
      ])),
      Logger.t('Backspace key on image', GeneralSteps.sequence([
        sTestBackspace('<p>a<a href="#"><img src="#" /></a>c</p>', [0, 2], 0, '<p>a<a href="#"><img src="#" /></a>c</p>', 'end', [0, 1, 1], 0),
        sTestBackspace('<p>a<a href="#"><img src="#" /></a>c</p>', [0, 1], 0, '<p>a<a href="#"><img src="#" /></a>c</p>', 'before', [0, 0], 1),
        tinyApis.sExecCommand('SelectAll'), // Needed for IE 11 for some odd reason the selection api is in some odd state
        sTestBackspace('<p>a<a href="#"><img src="#" />c</a>d</p>', [0, 1], 1, '<p>a<a href="#">c</a>d</p>', 'start', [0, 1, 0], 1)
      ])),
      Logger.t('Delete key on text', GeneralSteps.sequence([
        sTestDelete('<p>a<a href="#">b</a>c</p>', [0, 0], 1, '<p>a<a href="#">b</a>c</p>', 'start', [0, 1, 0], 1),
        sTestDelete('<p>a<a href="#">b</a>c</p>', [0, 1, 0], 1, '<p>a<a href="#">b</a>c</p>', 'after', [0, 2], 1),
        sTestDelete('<p>a<a href="#">bc</a>d</p>', [0, 1, 0], 1, '<p>a<a href="#">b</a>d</p>', 'end', [0, 1, 0], 1)
      ])),
      Logger.t('Delete key on image', GeneralSteps.sequence([
        sTestDelete('<p>a<a href="#"><img src="#" /></a>c</p>', [0, 0], 1, '<p>a<a href="#"><img src="#" /></a>c</p>', 'start', [0, 1, 0], 1),
        sTestDelete('<p>a<a href="#"><img src="#" /></a>c</p>', [0, 1], 1, '<p>a<a href="#"><img src="#" /></a>c</p>', 'after', [0, 2], 1),
        sTestDelete('<p>a<a href="#">b<img src="#" /></a>d</p>', [0, 1, 0], 1, '<p>a<a href="#">b</a>d</p>', 'end', [0, 1, 0], 1)
      ])),
      Logger.t('Backspace/delete last character', GeneralSteps.sequence([
        sTestDelete('<p>a<a href="#">b</a>c</p>', [0, 1, 0], 0, '<p>ac</p>', 'none', [0, 0], 1),
        sTestDelete('<p><img src="#1" /><a href="#">b</a><img src="#2" /></p>', [0, 1, 0], 0, '<p><img src="#1" /><img src="#2" /></p>', 'none', [0], 1),
        sTestDelete('<p>a<a href="#">b</a>c</p>', [0, 1, 0], 0, '<p>ac</p>', 'none', [0, 0], 1),
        tinyApis.sAssertContentStructure(paragraphWithText('ac')),
        sTestBackspace('<p>a<a href="#">b</a>c</p>', [0, 1, 0], 1, '<p>ac</p>', 'none', [0, 0], 1),
        tinyApis.sAssertContentStructure(paragraphWithText('ac')),
        sTestDelete('<p>a<a href="#"><img src="#1" /></a>c</p>', [0, 1], 0, '<p>ac</p>', 'none', [0, 0], 1),
        sTestBackspace('<p>a<a href="#"><img src="#1" /></a>c</p>', [0, 1], 1, '<p>ac</p>', 'none', [0, 0], 1)
      ])),
      Logger.t('Backspace/delete between blocks', GeneralSteps.sequence([
        sTestBackspace('<p><a href="#">a</a></p><p><a href="#">b</a></p>', [1], 0, '<p><a href="#">a</a><a href="#">b</a></p>', 'end', [0, 0, 0], 1),
        sTestDelete('<p><a href="#">a</a></p><p><a href="#">b</a></p>', [0], 1, '<p><a href="#">a</a><a href="#">b</a></p>', 'end', [0, 0, 0], 1)
      ])),
      Logger.t('Backspace key inline_boundaries: false', GeneralSteps.sequence([
        tinyApis.sSetSetting('inline_boundaries', false),
        sTestBackspace('<p>a<a href="#">b</a>c</p>', [0, 2], 0, '<p>a<a href="#">b</a>c</p>', 'after', [0, 2], 0),
        tinyApis.sSetSetting('inline_boundaries', true)
      ]))
    ], onSuccess, onFailure);
  }, {
Example #30
0
const sAssertSizeRecalcConstrainedReopen = function (ui) {
  return Logger.t('Assert constrained size recalculation on dialog reopen', GeneralSteps.sequence([
    sOpenDialog(ui),
    sPasteSourceValue(ui, 'http://test.se'),
    sAssertHeightAndWidth(ui, '150', '300'),
    sChangeWidthValue(ui, '350'),
    sAssertHeightAndWidth(ui, '175', '350'),
    sChangeHeightValue(ui, '100'),
    sAssertHeightAndWidth(ui, '100', '200'),
    sSubmitAndReopen(ui),
    sAssertHeightAndWidth(ui, '100', '200'),
    sChangeWidthValue(ui, '350'),
    sAssertHeightAndWidth(ui, '175', '350'),
    sCloseDialog(ui)
  ]));
};