diff --git a/functional-tests/helpers/constants.js b/functional-tests/helpers/constants.js index c43c65404..4a3e8aa08 100644 --- a/functional-tests/helpers/constants.js +++ b/functional-tests/helpers/constants.js @@ -21,6 +21,8 @@ const CLASS_BOX_PREVIEW_BASE_HEADER = 'bp-base-header'; exports.SELECTOR_BOX_PREVIEW_BASE_HEADER = `.${CLASS_BOX_PREVIEW_BASE_HEADER}`; const CLASS_ANNOTATION_BUTTON_POINT = 'bp-btn-annotate-point'; exports.SELECTOR_ANNOTATION_BUTTON_POINT = `.${CLASS_ANNOTATION_BUTTON_POINT}`; +const CLASS_ANNOTATION_BUTTON_DRAW = 'bp-btn-annotate-draw'; +exports.SELECTOR_ANNOTATION_BUTTON_DRAW = `.${CLASS_ANNOTATION_BUTTON_DRAW}`; const CLASS_ANNOTATION_BUTTON_DRAW_ENTER = 'bp-btn-annotate-draw-enter'; exports.SELECTOR_ANNOTATION_BUTTON_DRAW_ENTER = `.${CLASS_ANNOTATION_BUTTON_DRAW_ENTER}`; @@ -159,8 +161,6 @@ exports.SELECTOR_ANNOTATION_LAYER_DRAW_IN_PROGRESS = `.${CLASS_ANNOTATION_LAYER_ // Drawing CSS constants const CLASS_ANNOTATION_DRAW = 'ba-annotation-draw'; exports.SELECTOR_ANNOTATION_DRAW = `.${CLASS_ANNOTATION_DRAW}`; -const CLASS_ANNOTATION_BUTTON_DRAW = 'ba-btn-annotate-draw'; -exports.SELECTOR_ANNOTATION_BUTTON_DRAW = `.${CLASS_ANNOTATION_BUTTON_DRAW}`; const CLASS_ANNOTATION_BUTTON_DRAW_UNDO = 'ba-btn-annotate-draw-undo'; exports.SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO = `.${CLASS_ANNOTATION_BUTTON_DRAW_UNDO}`; const CLASS_ANNOTATION_BUTTON_DRAW_REDO = 'ba-btn-annotate-draw-redo'; diff --git a/functional-tests/helpers/mouseEvents.js b/functional-tests/helpers/mouseEvents.js index 64e8bad3c..e8ce9bdfe 100644 --- a/functional-tests/helpers/mouseEvents.js +++ b/functional-tests/helpers/mouseEvents.js @@ -1,3 +1,5 @@ +/* eslint-disable prefer-arrow-callback, no-var, func-names */ + /** * Selects text on the document * @@ -51,4 +53,53 @@ function selectText(I, selector) { ); } -exports.selectText = selectText; \ No newline at end of file +/** + * Draw on the document + * + * @param {Object} I - the codeceptjs I + * @param {string} selector - the selector to use + * + * @return {void} + */ +function draw(I, selector) { + I.waitForElement(selector); + + I.executeScript( + function (sel) { + const preview = document.querySelector('.bp-doc'); + const selectionEl = document.querySelector(sel); + const start = selectionEl.firstElementChild; + const end = selectionEl.lastElementChild; + + /** + * Cross browser event creation + * @param {string} eventName the event name + * @param {HTMLElement} el - the DOM element to use + * @return {Event} the event + */ + function createNewEvent(eventName, el) { + const x = el.offsetLeft + 2; + const y = el.offsetTop + 2; + + let event; + if (typeof MouseEvent === 'function') { + event = new MouseEvent(eventName, { + bubbles: true, + clientX: x, + clientY: y + }); + } + + return event; + } + + preview.dispatchEvent(createNewEvent('mousedown', start)); + preview.dispatchEvent(createNewEvent('mousemove', end)); + preview.dispatchEvent(createNewEvent('mouseup', end)); + }, + selector + ); +} + +exports.selectText = selectText; +exports.draw = draw; diff --git a/functional-tests/tests/draw.js b/functional-tests/tests/draw.js new file mode 100644 index 000000000..6c450977c --- /dev/null +++ b/functional-tests/tests/draw.js @@ -0,0 +1,85 @@ +const { + SELECTOR_DISABLED, + SELECTOR_ANNOTATIONS_LOADED, + SELECTOR_ANNNOTATION_MODE_BACKGROUND, + SELECTOR_ANNOTATION_BUTTON_DRAW, + SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO, + SELECTOR_ANNOTATION_BUTTON_DRAW_REDO, + SELECTOR_ANNOTATION_BUTTON_DRAW_POST, + SELECTOR_ANNOTATION_BUTTON_DRAW_CANCEL, + SELECTOR_ANNOTATION_LAYER_DRAW_IN_PROGRESS, + SELECTOR_ANNOTATION_DRAWING_DIALOG, + SELECTOR_ADD_DRAWING_BTN, + SELECTOR_DELETE_DRAWING_BTN +} = require('../helpers/constants'); + +const { draw } = require('../helpers/mouseEvents'); + +Feature('Draw Annotation Sanity'); + +Before((I) => { + I.amOnPage('/'); +}); + +Scenario('Can enter/exit drawing mode properly @desktop @enabled', (I) => { + I.waitForVisible(SELECTOR_ANNOTATIONS_LOADED); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW); + + I.say('Enter draw annotation mode'); + I.click(SELECTOR_ANNOTATION_BUTTON_DRAW); + I.waitForVisible('.bp-notification'); + I.waitForVisible(SELECTOR_ANNNOTATION_MODE_BACKGROUND); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW_POST); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW_CANCEL); + + I.say('Undo/redo buttons should be disabled'); + I.waitForVisible(`${SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO}${SELECTOR_DISABLED}`); + I.waitForVisible(`${SELECTOR_ANNOTATION_BUTTON_DRAW_REDO}${SELECTOR_DISABLED}`); + + I.say('Exit draw annotations mode'); + I.click(SELECTOR_ANNOTATION_BUTTON_DRAW_CANCEL); + I.dontSeeElement(SELECTOR_ANNNOTATION_MODE_BACKGROUND); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW); +}); + +Scenario('Cancel a new drawing annotation @desktop @enabled', (I) => { + I.waitForVisible(SELECTOR_ANNOTATIONS_LOADED); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW); + + I.say('Enter draw annotation mode'); + I.click(SELECTOR_ANNOTATION_BUTTON_DRAW); + I.click('.textLayer'); + + draw(I, '.textLayer'); + I.waitForVisible(SELECTOR_ANNOTATION_LAYER_DRAW_IN_PROGRESS); + I.waitForVisible(SELECTOR_ANNOTATION_DRAWING_DIALOG); + + I.say('Undo/redo buttons should be disabled'); + I.waitForEnabled(SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO); + I.waitForVisible(`${SELECTOR_ANNOTATION_BUTTON_DRAW_REDO}${SELECTOR_DISABLED}`); + + I.say('Cancel drawing'); + I.click(SELECTOR_DELETE_DRAWING_BTN); + I.waitForInvisible(SELECTOR_ANNOTATION_DRAWING_DIALOG); +}); + +Scenario('Create a drawing annotation @desktop @enabled', (I) => { + I.waitForVisible(SELECTOR_ANNOTATIONS_LOADED); + I.waitForVisible(SELECTOR_ANNOTATION_BUTTON_DRAW); + + I.say('Enter draw annotation mode'); + I.click(SELECTOR_ANNOTATION_BUTTON_DRAW); + I.click('.textLayer'); + + draw(I, '.textLayer'); + I.waitForVisible(SELECTOR_ANNOTATION_LAYER_DRAW_IN_PROGRESS); + I.waitForVisible(SELECTOR_ANNOTATION_DRAWING_DIALOG); + + I.say('Undo/redo buttons should be disabled'); + I.waitForEnabled(SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO); + I.waitForVisible(`${SELECTOR_ANNOTATION_BUTTON_DRAW_REDO}${SELECTOR_DISABLED}`); + + I.say('Save drawing'); + I.click(SELECTOR_ADD_DRAWING_BTN); + I.waitForInvisible(SELECTOR_ANNOTATION_DRAWING_DIALOG); +}); \ No newline at end of file diff --git a/src/constants.js b/src/constants.js index 5cfdb0030..43218ccbe 100644 --- a/src/constants.js +++ b/src/constants.js @@ -23,6 +23,8 @@ export const CLASS_BOX_PREVIEW_BASE_HEADER = 'bp-base-header'; export const SELECTOR_BOX_PREVIEW_BASE_HEADER = `.${CLASS_BOX_PREVIEW_BASE_HEADER}`; export const CLASS_ANNOTATION_BUTTON_POINT = 'bp-btn-annotate-point'; export const SELECTOR_ANNOTATION_BUTTON_POINT = `.${CLASS_ANNOTATION_BUTTON_POINT}`; +export const CLASS_ANNOTATION_BUTTON_DRAW = 'bp-btn-annotate-draw'; +export const SELECTOR_ANNOTATION_BUTTON_DRAW = `.${CLASS_ANNOTATION_BUTTON_DRAW}`; export const CLASS_ANNOTATION_BUTTON_DRAW_ENTER = 'bp-btn-annotate-draw-enter'; export const SELECTOR_ANNOTATION_BUTTON_DRAW_ENTER = `.${CLASS_ANNOTATION_BUTTON_DRAW_ENTER}`; @@ -161,8 +163,6 @@ export const SELECTOR_ANNOTATION_LAYER_DRAW_IN_PROGRESS = `.${CLASS_ANNOTATION_L // Drawing CSS constants export const CLASS_ANNOTATION_DRAW = 'ba-annotation-draw'; export const SELECTOR_ANNOTATION_DRAW = `.${CLASS_ANNOTATION_DRAW}`; -export const CLASS_ANNOTATION_BUTTON_DRAW = 'ba-btn-annotate-draw'; -export const SELECTOR_ANNOTATION_BUTTON_DRAW = `.${CLASS_ANNOTATION_BUTTON_DRAW}`; export const CLASS_ANNOTATION_BUTTON_DRAW_UNDO = 'ba-btn-annotate-draw-undo'; export const SELECTOR_ANNOTATION_BUTTON_DRAW_UNDO = `.${CLASS_ANNOTATION_BUTTON_DRAW_UNDO}`; export const CLASS_ANNOTATION_BUTTON_DRAW_REDO = 'ba-btn-annotate-draw-redo'; diff --git a/src/doc/DocAnnotator.js b/src/doc/DocAnnotator.js index 99d5844e7..8d43c66e0 100644 --- a/src/doc/DocAnnotator.js +++ b/src/doc/DocAnnotator.js @@ -158,7 +158,10 @@ class DocAnnotator extends Annotator { // If click isn't on a page, ignore const eventTarget = clientEvent.target; const pageInfo = util.getPageInfo(eventTarget); - if (!pageInfo.pageEl) { + const pageEl = pageInfo.pageEl + ? pageInfo.pageEl + : this.annotatedElement.querySelector(`[data-page-number="${pageInfo.page}"]`); + if (!pageEl) { return location; } @@ -174,7 +177,7 @@ class DocAnnotator extends Annotator { } // Store coordinates at 100% scale in PDF space in PDF units - const pageDimensions = pageInfo.pageEl.getBoundingClientRect(); + const pageDimensions = pageEl.getBoundingClientRect(); const pageWidth = pageDimensions.width; const pageHeight = pageDimensions.height - PAGE_PADDING_TOP - PAGE_PADDING_BOTTOM; const browserCoordinates = [