first commit
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Types tests / Test (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				Lint / Lint (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				CodeQL / Analyze (javascript) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (20) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (22) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (24) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Types tests / Test (lts/*) (push) Has been cancelled
				
			Lint / Lint (lts/*) (push) Has been cancelled
				
			CodeQL / Analyze (javascript) (push) Has been cancelled
				
			CI / Test (20) (push) Has been cancelled
				
			CI / Test (22) (push) Has been cancelled
				
			CI / Test (24) (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										627
									
								
								test/integration/comment_spec.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								test/integration/comment_spec.mjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,627 @@
 | 
			
		||||
/* Copyright 2025 Mozilla Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  awaitPromise,
 | 
			
		||||
  closePages,
 | 
			
		||||
  createPromise,
 | 
			
		||||
  dragAndDrop,
 | 
			
		||||
  getEditorSelector,
 | 
			
		||||
  getRect,
 | 
			
		||||
  getSpanRectFromText,
 | 
			
		||||
  loadAndWait,
 | 
			
		||||
  scrollIntoView,
 | 
			
		||||
  selectEditor,
 | 
			
		||||
  switchToEditor,
 | 
			
		||||
  waitAndClick,
 | 
			
		||||
  waitForSerialized,
 | 
			
		||||
} from "./test_utils.mjs";
 | 
			
		||||
 | 
			
		||||
const switchToHighlight = switchToEditor.bind(null, "Highlight");
 | 
			
		||||
const switchToStamp = switchToEditor.bind(null, "Stamp");
 | 
			
		||||
const switchToComment = switchToEditor.bind(null, "Comment");
 | 
			
		||||
 | 
			
		||||
const highlightSpan = async (page, pageIndex, text) => {
 | 
			
		||||
  const rect = await getSpanRectFromText(page, pageIndex, text);
 | 
			
		||||
  const x = rect.x + rect.width / 2;
 | 
			
		||||
  const y = rect.y + rect.height / 2;
 | 
			
		||||
  await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
  await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const editComment = async (page, editorSelector, comment) => {
 | 
			
		||||
  const commentButtonSelector = `${editorSelector} button.comment`;
 | 
			
		||||
  await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
  const textInputSelector = "#commentManagerTextInput";
 | 
			
		||||
  await page.waitForSelector(textInputSelector, {
 | 
			
		||||
    visible: true,
 | 
			
		||||
  });
 | 
			
		||||
  await page.type(textInputSelector, comment);
 | 
			
		||||
  await waitAndClick(page, "#commentManagerSaveButton");
 | 
			
		||||
  await page.waitForSelector("#commentManagerDialog", {
 | 
			
		||||
    visible: false,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
describe("Comment", () => {
 | 
			
		||||
  describe("Comment edit dialog must be visible in ltr", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "bug1989304.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must set the comment dialog in the viewport (LTR)", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          await scrollIntoView(page, ".textLayer span:last-of-type");
 | 
			
		||||
          const rect = await getSpanRectFromText(page, 1, "...");
 | 
			
		||||
          const x = rect.x + rect.width / 2;
 | 
			
		||||
          const y = rect.y + rect.height / 2;
 | 
			
		||||
          // Here and elsewhere, we add a small delay between press and release
 | 
			
		||||
          // to make sure that a pointerup event is triggered after
 | 
			
		||||
          // selectionchange.
 | 
			
		||||
          // It works with a value of 1ms, but we use 100ms to be sure.
 | 
			
		||||
          await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
          await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
 | 
			
		||||
          const commentButtonSelector = `${getEditorSelector(0)} button.comment`;
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          await page.waitForSelector("#commentManagerDialog", {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          const dialogRect = await getRect(page, "#commentManagerDialog");
 | 
			
		||||
          const viewport = await page.evaluate(() => ({
 | 
			
		||||
            width: document.documentElement.clientWidth,
 | 
			
		||||
            height: document.documentElement.clientHeight,
 | 
			
		||||
          }));
 | 
			
		||||
          expect(dialogRect.x + dialogRect.width)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(viewport.width + 1);
 | 
			
		||||
          expect(dialogRect.y + dialogRect.height)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(viewport.height + 1);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Comment edit dialog must be visible in rtl", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "bug1989304.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true, localeProperties: "ar" }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must set the comment dialog in the viewport (RTL)", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          await scrollIntoView(page, ".textLayer span:nth-of-type(4)");
 | 
			
		||||
          const rect = await getSpanRectFromText(page, 1, "World");
 | 
			
		||||
          const x = rect.x + rect.width / 2;
 | 
			
		||||
          const y = rect.y + rect.height / 2;
 | 
			
		||||
          await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
          await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
 | 
			
		||||
          const commentButtonSelector = `${getEditorSelector(0)} button.comment`;
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          await page.waitForSelector("#commentManagerDialog", {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          const dialogRect = await getRect(page, "#commentManagerDialog");
 | 
			
		||||
          const viewport = await page.evaluate(() => ({
 | 
			
		||||
            height: window.innerHeight,
 | 
			
		||||
          }));
 | 
			
		||||
          expect(dialogRect.x + dialogRect.width)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeGreaterThanOrEqual(-1);
 | 
			
		||||
          expect(dialogRect.y + dialogRect.height)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(viewport.height + 1);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Update comment position and color in reading mode", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "comments.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-fit",
 | 
			
		||||
        null,
 | 
			
		||||
        {
 | 
			
		||||
          enableComment: true,
 | 
			
		||||
          highlightEditorColors:
 | 
			
		||||
            "yellow=#FFFF00,green=#00FF00,blue=#0000FF,pink=#FF00FF,red=#FF0000",
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must set the comment button at the right place", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToStamp(page);
 | 
			
		||||
 | 
			
		||||
          const stampSelector = getEditorSelector(8);
 | 
			
		||||
          await selectEditor(page, stampSelector);
 | 
			
		||||
          await dragAndDrop(page, stampSelector, [[100, 100]]);
 | 
			
		||||
          await waitForSerialized(page, 1);
 | 
			
		||||
          const rectCommentButton = await getRect(
 | 
			
		||||
            page,
 | 
			
		||||
            `${stampSelector} .annotationCommentButton`
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          await switchToStamp(page, /* disable = */ true);
 | 
			
		||||
          const rectCommentButtonAfter = await getRect(
 | 
			
		||||
            page,
 | 
			
		||||
            `#pdfjs_internal_id_713R + .annotationCommentButton`
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          expect(Math.abs(rectCommentButtonAfter.x - rectCommentButton.x))
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(1);
 | 
			
		||||
          expect(Math.abs(rectCommentButtonAfter.y - rectCommentButton.y))
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(1);
 | 
			
		||||
          expect(
 | 
			
		||||
            Math.abs(rectCommentButtonAfter.width - rectCommentButton.width)
 | 
			
		||||
          )
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(1);
 | 
			
		||||
          expect(
 | 
			
		||||
            Math.abs(rectCommentButtonAfter.height - rectCommentButton.height)
 | 
			
		||||
          )
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toBeLessThanOrEqual(1);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must set the right color to the comment button", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          const highlightSelector = getEditorSelector(0);
 | 
			
		||||
          await selectEditor(page, highlightSelector);
 | 
			
		||||
          const colorButtonSelector = `${highlightSelector} .editToolbar button`;
 | 
			
		||||
          await page.waitForSelector(`${colorButtonSelector}.colorPicker`);
 | 
			
		||||
          await page.click(`${colorButtonSelector}.colorPicker`);
 | 
			
		||||
          await page.waitForSelector(`${colorButtonSelector}[title = "Red"]`);
 | 
			
		||||
          await page.click(`${colorButtonSelector}[title = "Red"]`);
 | 
			
		||||
          await page.waitForSelector(
 | 
			
		||||
            `.page[data-page-number = "1"] svg.highlight[fill = "#FF0000"]`
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          const commentButtonColor = await page.evaluate(selector => {
 | 
			
		||||
            const button = document.querySelector(
 | 
			
		||||
              `${selector} .annotationCommentButton`
 | 
			
		||||
            );
 | 
			
		||||
            return window.getComputedStyle(button).backgroundColor;
 | 
			
		||||
          }, highlightSelector);
 | 
			
		||||
 | 
			
		||||
          await switchToHighlight(page, /* disable = */ true);
 | 
			
		||||
 | 
			
		||||
          const commentButtonColorAfter = await page.evaluate(() => {
 | 
			
		||||
            const button = document.querySelector(
 | 
			
		||||
              "section[data-annotation-id='612R'] + .annotationCommentButton"
 | 
			
		||||
            );
 | 
			
		||||
            return window.getComputedStyle(button).backgroundColor;
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          expect(commentButtonColorAfter)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toEqual(commentButtonColor);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Comment buttons", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "tracemonkey.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that the comment button has a title", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          const rect = await getSpanRectFromText(page, 1, "Languages");
 | 
			
		||||
          const x = rect.x + rect.width / 2;
 | 
			
		||||
          const y = rect.y + rect.height / 2;
 | 
			
		||||
          await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
          await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
 | 
			
		||||
          let commentButtonSelector = `${getEditorSelector(0)} button.comment`;
 | 
			
		||||
          await page.waitForSelector(commentButtonSelector, { visible: true });
 | 
			
		||||
          let title = await page.evaluate(
 | 
			
		||||
            selector => document.querySelector(selector).title,
 | 
			
		||||
            commentButtonSelector
 | 
			
		||||
          );
 | 
			
		||||
          expect(title)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toEqual("Edit comment");
 | 
			
		||||
          await page.click(commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          const textInputSelector = "#commentManagerTextInput";
 | 
			
		||||
          await page.waitForSelector(textInputSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          await page.type(textInputSelector, "Hello world!");
 | 
			
		||||
 | 
			
		||||
          await page.click("#commentManagerSaveButton");
 | 
			
		||||
 | 
			
		||||
          commentButtonSelector = `${getEditorSelector(0)} button.annotationCommentButton`;
 | 
			
		||||
          await page.waitForSelector(commentButtonSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          title = await page.evaluate(selector => {
 | 
			
		||||
            const button = document.querySelector(selector);
 | 
			
		||||
            return button.title;
 | 
			
		||||
          }, commentButtonSelector);
 | 
			
		||||
          expect(title)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toEqual("Show comment");
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that the comment button is added in the annotation layer", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          const rect = await getSpanRectFromText(page, 1, "Abstract");
 | 
			
		||||
          const x = rect.x + rect.width / 2;
 | 
			
		||||
          const y = rect.y + rect.height / 2;
 | 
			
		||||
          await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
          await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
 | 
			
		||||
          const comment = "Hello world!";
 | 
			
		||||
          await editComment(page, getEditorSelector(0), comment);
 | 
			
		||||
          await page.hover("#editorHighlightButton");
 | 
			
		||||
          let buttonSelector =
 | 
			
		||||
            ".annotationEditorLayer .annotationCommentButton";
 | 
			
		||||
          await page.waitForSelector(buttonSelector, { visible: true });
 | 
			
		||||
          await page.hover(buttonSelector);
 | 
			
		||||
          const popupSelector = "#commentPopup";
 | 
			
		||||
          await page.waitForSelector(popupSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          let popupText = await page.evaluate(
 | 
			
		||||
            selector => document.querySelector(selector).textContent,
 | 
			
		||||
            `${popupSelector} .commentPopupText`
 | 
			
		||||
          );
 | 
			
		||||
          expect(popupText).withContext(`In ${browserName}`).toEqual(comment);
 | 
			
		||||
 | 
			
		||||
          await page.hover("#editorHighlightButton");
 | 
			
		||||
          await switchToHighlight(page, /* disable = */ true);
 | 
			
		||||
 | 
			
		||||
          buttonSelector = ".annotationLayer .annotationCommentButton";
 | 
			
		||||
          await page.waitForSelector(buttonSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          await page.hover(buttonSelector);
 | 
			
		||||
 | 
			
		||||
          await page.waitForSelector(popupSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          popupText = await page.evaluate(
 | 
			
		||||
            selector => document.querySelector(selector).textContent,
 | 
			
		||||
            `${popupSelector} .commentPopupText`
 | 
			
		||||
          );
 | 
			
		||||
          expect(popupText).withContext(`In ${browserName}`).toEqual(comment);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Focused element after editing", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "tracemonkey.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that the focus is moved on the comment button", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
 | 
			
		||||
          const rect = await getSpanRectFromText(page, 1, "Languages");
 | 
			
		||||
          const x = rect.x + rect.width / 2;
 | 
			
		||||
          const y = rect.y + rect.height / 2;
 | 
			
		||||
          await page.mouse.click(x, y, { count: 2, delay: 100 });
 | 
			
		||||
          await page.waitForSelector(getEditorSelector(0));
 | 
			
		||||
 | 
			
		||||
          const commentButtonSelector = `${getEditorSelector(0)} button.comment`;
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          await page.waitForSelector("#commentManagerCancelButton", {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          const handle = await createPromise(page, resolve => {
 | 
			
		||||
            document
 | 
			
		||||
              .querySelector("button.comment")
 | 
			
		||||
              .addEventListener("focus", resolve, { once: true });
 | 
			
		||||
          });
 | 
			
		||||
          await page.click("#commentManagerCancelButton");
 | 
			
		||||
          await awaitPromise(handle);
 | 
			
		||||
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          const textInputSelector = "#commentManagerTextInput";
 | 
			
		||||
          await page.waitForSelector(textInputSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          await page.type(textInputSelector, "Hello world!");
 | 
			
		||||
 | 
			
		||||
          await page.click("#commentManagerSaveButton");
 | 
			
		||||
          await page.waitForSelector("button.annotationCommentButton", {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          await page.waitForFunction(
 | 
			
		||||
            sel => document.activeElement === document.querySelector(sel),
 | 
			
		||||
            {},
 | 
			
		||||
            "button.annotationCommentButton"
 | 
			
		||||
          );
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Focused element after editing in reading mode", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "comments.pdf",
 | 
			
		||||
        ".annotationLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that the focus is moved on the comment button", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          const commentButtonSelector = `[data-annotation-id="612R"] + button.annotationCommentButton`;
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
          const commentPopupSelector = "#commentPopup";
 | 
			
		||||
          const editButtonSelector = `${commentPopupSelector} button.commentPopupEdit`;
 | 
			
		||||
          await waitAndClick(page, editButtonSelector);
 | 
			
		||||
 | 
			
		||||
          await page.waitForSelector("#commentManagerCancelButton", {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          let handle = await createPromise(page, resolve => {
 | 
			
		||||
            document
 | 
			
		||||
              .querySelector(
 | 
			
		||||
                `[data-annotation-id="612R"] + button.annotationCommentButton`
 | 
			
		||||
              )
 | 
			
		||||
              .addEventListener("focus", resolve, { once: true });
 | 
			
		||||
          });
 | 
			
		||||
          await page.click("#commentManagerCancelButton");
 | 
			
		||||
          await awaitPromise(handle);
 | 
			
		||||
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
          await waitAndClick(page, editButtonSelector);
 | 
			
		||||
 | 
			
		||||
          const textInputSelector = "#commentManagerTextInput";
 | 
			
		||||
          await page.waitForSelector(textInputSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          await page.type(textInputSelector, "Hello world!");
 | 
			
		||||
 | 
			
		||||
          handle = await createPromise(page, resolve => {
 | 
			
		||||
            document
 | 
			
		||||
              .querySelector(
 | 
			
		||||
                `[data-annotation-id="612R"] + button.annotationCommentButton`
 | 
			
		||||
              )
 | 
			
		||||
              .addEventListener("focus", resolve, { once: true });
 | 
			
		||||
          });
 | 
			
		||||
          await page.click("#commentManagerSaveButton");
 | 
			
		||||
          await awaitPromise(handle);
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Comment sidebar", () => {
 | 
			
		||||
    let pages;
 | 
			
		||||
 | 
			
		||||
    beforeEach(async () => {
 | 
			
		||||
      pages = await loadAndWait(
 | 
			
		||||
        "comments.pdf",
 | 
			
		||||
        ".annotationEditorLayer",
 | 
			
		||||
        "page-width",
 | 
			
		||||
        null,
 | 
			
		||||
        { enableComment: true }
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(async () => {
 | 
			
		||||
      await closePages(pages);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that the comment sidebar is resizable", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToComment(page);
 | 
			
		||||
 | 
			
		||||
          const sidebarSelector = "#editorCommentParamsToolbar";
 | 
			
		||||
          for (const extraWidth of [100, -100]) {
 | 
			
		||||
            const rect = await getRect(page, sidebarSelector);
 | 
			
		||||
            const resizerRect = await getRect(
 | 
			
		||||
              page,
 | 
			
		||||
              "#editorCommentsSidebarResizer"
 | 
			
		||||
            );
 | 
			
		||||
            const startX = resizerRect.x + resizerRect.width / 2;
 | 
			
		||||
            const startY = resizerRect.y + 2;
 | 
			
		||||
            await page.mouse.move(startX, startY);
 | 
			
		||||
            await page.mouse.down();
 | 
			
		||||
 | 
			
		||||
            const steps = 20;
 | 
			
		||||
            await page.mouse.move(startX - extraWidth, startY, { steps });
 | 
			
		||||
            await page.mouse.up();
 | 
			
		||||
 | 
			
		||||
            const rectAfter = await getRect(page, sidebarSelector);
 | 
			
		||||
            expect(Math.abs(rectAfter.width - (rect.width + extraWidth)))
 | 
			
		||||
              .withContext(`In ${browserName}`)
 | 
			
		||||
              .toBeLessThanOrEqual(1);
 | 
			
		||||
            expect(Math.abs(rectAfter.x - (rect.x - extraWidth)))
 | 
			
		||||
              .withContext(`In ${browserName}`)
 | 
			
		||||
              .toBeLessThanOrEqual(1);
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that comments are in chronological order", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToComment(page);
 | 
			
		||||
 | 
			
		||||
          const checkDates = async () => {
 | 
			
		||||
            const dates = await page.evaluate(() =>
 | 
			
		||||
              Array.from(
 | 
			
		||||
                document.querySelectorAll(
 | 
			
		||||
                  `#editorCommentParamsToolbar ul > li > time`
 | 
			
		||||
                )
 | 
			
		||||
              ).map(time => new Date(time.getAttribute("datetime")))
 | 
			
		||||
            );
 | 
			
		||||
            for (let i = 0; i < dates.length - 1; i++) {
 | 
			
		||||
              expect(dates[i])
 | 
			
		||||
                .withContext(`In ${browserName}`)
 | 
			
		||||
                .toBeGreaterThanOrEqual(dates[i + 1]);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          await checkDates();
 | 
			
		||||
 | 
			
		||||
          // Add an highlight with a comment and check the order again.
 | 
			
		||||
          await switchToHighlight(page);
 | 
			
		||||
          await highlightSpan(page, 1, "Languages");
 | 
			
		||||
          const editorSelector = getEditorSelector(9);
 | 
			
		||||
          await page.waitForSelector(editorSelector);
 | 
			
		||||
          const commentButtonSelector = `${editorSelector} button.comment`;
 | 
			
		||||
          await waitAndClick(page, commentButtonSelector);
 | 
			
		||||
 | 
			
		||||
          const textInputSelector = "#commentManagerTextInput";
 | 
			
		||||
          await page.waitForSelector(textInputSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          await page.type(textInputSelector, "Hello world!");
 | 
			
		||||
          await page.click("#commentManagerSaveButton");
 | 
			
		||||
          await waitForSerialized(page, 1);
 | 
			
		||||
 | 
			
		||||
          await switchToComment(page);
 | 
			
		||||
          await checkDates();
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("must check that comments can be selected/unselected", async () => {
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        pages.map(async ([browserName, page]) => {
 | 
			
		||||
          await switchToComment(page);
 | 
			
		||||
 | 
			
		||||
          const firstElementSelector =
 | 
			
		||||
            "#editorCommentsSidebarList li:first-child";
 | 
			
		||||
          await waitAndClick(page, firstElementSelector);
 | 
			
		||||
          const popupSelector = "#commentPopup";
 | 
			
		||||
          await page.waitForSelector(popupSelector, { visible: true });
 | 
			
		||||
          const popupTextSelector = `${popupSelector} .commentPopupText`;
 | 
			
		||||
          await page.waitForSelector(popupTextSelector, {
 | 
			
		||||
            visible: true,
 | 
			
		||||
          });
 | 
			
		||||
          const popupText = await page.evaluate(
 | 
			
		||||
            selector => document.querySelector(selector).textContent,
 | 
			
		||||
            popupTextSelector
 | 
			
		||||
          );
 | 
			
		||||
          expect(popupText)
 | 
			
		||||
            .withContext(`In ${browserName}`)
 | 
			
		||||
            .toEqual("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 | 
			
		||||
 | 
			
		||||
          // Click again to unselect the comment.
 | 
			
		||||
          await waitAndClick(page, firstElementSelector);
 | 
			
		||||
          await page.waitForSelector(popupSelector, { visible: false });
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user