fix: rotation functionality for PDF page and add corresponding tests
This commit is contained in:
@@ -261,6 +261,9 @@ async function generateI18nPages() {
|
|||||||
if (processed % 10 === 0 || processed === total) {
|
if (processed % 10 === 0 || processed === total) {
|
||||||
console.log(` Progress: ${processed}/${total} pages`);
|
console.log(` Progress: ${processed}/${total} pages`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up JSDOM instances
|
||||||
|
await new Promise((resolve) => setImmediate(resolve));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEnglishFile(filePath, originalContent);
|
updateEnglishFile(filePath, originalContent);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ input[type='file']::file-selector-button {
|
|||||||
color: #39a0ed;
|
color: #39a0ed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-thumbnail,
|
#page-organizer .page-thumbnail,
|
||||||
#file-list > li {
|
#file-list > li {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,9 +496,7 @@ export async function extractPageModel(
|
|||||||
page: pdfjsLib.PDFPageProxy,
|
page: pdfjsLib.PDFPageProxy,
|
||||||
viewport: pdfjsLib.PageViewport
|
viewport: pdfjsLib.PageViewport
|
||||||
): Promise<ComparePageModel> {
|
): Promise<ComparePageModel> {
|
||||||
const textContent = await page.getTextContent({
|
const textContent = await page.getTextContent();
|
||||||
disableCombineTextItems: true,
|
|
||||||
});
|
|
||||||
const styles = textContent.styles ?? {};
|
const styles = textContent.styles ?? {};
|
||||||
const rawItems = sortCompareTextItems(
|
const rawItems = sortCompareTextItems(
|
||||||
textContent.items
|
textContent.items
|
||||||
|
|||||||
@@ -98,38 +98,40 @@ function createPageWrapper(
|
|||||||
|
|
||||||
const rotateLeftBtn = document.createElement('button');
|
const rotateLeftBtn = document.createElement('button');
|
||||||
rotateLeftBtn.className =
|
rotateLeftBtn.className =
|
||||||
'flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs';
|
'flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs cursor-pointer';
|
||||||
rotateLeftBtn.innerHTML = '<i data-lucide="rotate-ccw" class="w-3 h-3"></i>';
|
rotateLeftBtn.innerHTML = '<i data-lucide="rotate-ccw" class="w-3 h-3"></i>';
|
||||||
rotateLeftBtn.onclick = function (e) {
|
rotateLeftBtn.addEventListener('click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
pageState.rotations[pageIndex] = pageState.rotations[pageIndex] - 90;
|
pageState.rotations[pageIndex] = pageState.rotations[pageIndex] - 90;
|
||||||
const wrapper = container.querySelector(
|
const wrapper = container.querySelector(
|
||||||
'.thumbnail-wrapper'
|
'.thumbnail-wrapper'
|
||||||
) as HTMLElement;
|
) as HTMLElement;
|
||||||
if (wrapper)
|
if (wrapper)
|
||||||
wrapper.style.transform = `rotate(${pageState.rotations[pageIndex]}deg)`;
|
wrapper.style.transform = `rotate(${pageState.rotations[pageIndex]}deg)`;
|
||||||
};
|
});
|
||||||
|
|
||||||
const rotateRightBtn = document.createElement('button');
|
const rotateRightBtn = document.createElement('button');
|
||||||
rotateRightBtn.className =
|
rotateRightBtn.className =
|
||||||
'flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs';
|
'flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs cursor-pointer';
|
||||||
rotateRightBtn.innerHTML = '<i data-lucide="rotate-cw" class="w-3 h-3"></i>';
|
rotateRightBtn.innerHTML = '<i data-lucide="rotate-cw" class="w-3 h-3"></i>';
|
||||||
rotateRightBtn.onclick = function (e) {
|
rotateRightBtn.addEventListener('click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
pageState.rotations[pageIndex] = pageState.rotations[pageIndex] + 90;
|
pageState.rotations[pageIndex] = pageState.rotations[pageIndex] + 90;
|
||||||
const wrapper = container.querySelector(
|
const wrapper = container.querySelector(
|
||||||
'.thumbnail-wrapper'
|
'.thumbnail-wrapper'
|
||||||
) as HTMLElement;
|
) as HTMLElement;
|
||||||
if (wrapper)
|
if (wrapper)
|
||||||
wrapper.style.transform = `rotate(${pageState.rotations[pageIndex]}deg)`;
|
wrapper.style.transform = `rotate(${pageState.rotations[pageIndex]}deg)`;
|
||||||
};
|
});
|
||||||
|
|
||||||
controls.append(rotateLeftBtn, rotateRightBtn);
|
controls.append(rotateLeftBtn, rotateRightBtn);
|
||||||
container.appendChild(controls);
|
container.appendChild(controls);
|
||||||
|
|
||||||
// Re-create icons for the new element
|
// Re-create icons scoped to this container only
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
createIcons({ icons });
|
createIcons({ icons, nameAttr: 'data-lucide', attrs: {} });
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
|
|||||||
380
src/tests/rotate-pdf-page.test.ts
Normal file
380
src/tests/rotate-pdf-page.test.ts
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||||
|
|
||||||
|
interface RotateState {
|
||||||
|
rotations: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTestState(pageCount: number): RotateState {
|
||||||
|
return { rotations: new Array(pageCount).fill(0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPageWrapper(
|
||||||
|
pageNumber: number,
|
||||||
|
state: RotateState
|
||||||
|
): HTMLElement {
|
||||||
|
const pageIndex = pageNumber - 1;
|
||||||
|
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.className =
|
||||||
|
'page-thumbnail relative bg-gray-700 rounded-lg overflow-hidden';
|
||||||
|
container.dataset.pageIndex = pageIndex.toString();
|
||||||
|
container.dataset.pageNumber = pageNumber.toString();
|
||||||
|
|
||||||
|
const canvasWrapper = document.createElement('div');
|
||||||
|
canvasWrapper.className =
|
||||||
|
'thumbnail-wrapper flex items-center justify-center p-2 h-36';
|
||||||
|
canvasWrapper.style.transition = 'transform 0.3s ease';
|
||||||
|
const initialRotation = state.rotations[pageIndex] || 0;
|
||||||
|
canvasWrapper.style.transform = `rotate(${initialRotation}deg)`;
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.className = 'max-w-full max-h-full object-contain';
|
||||||
|
canvasWrapper.appendChild(canvas);
|
||||||
|
|
||||||
|
container.appendChild(canvasWrapper);
|
||||||
|
|
||||||
|
const controls = document.createElement('div');
|
||||||
|
controls.className = 'flex items-center justify-center gap-2 p-2 bg-gray-800';
|
||||||
|
|
||||||
|
const rotateLeftBtn = document.createElement('button');
|
||||||
|
rotateLeftBtn.className =
|
||||||
|
'rotate-left-btn flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs cursor-pointer';
|
||||||
|
rotateLeftBtn.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
state.rotations[pageIndex] = state.rotations[pageIndex] - 90;
|
||||||
|
const wrapper = container.querySelector(
|
||||||
|
'.thumbnail-wrapper'
|
||||||
|
) as HTMLElement;
|
||||||
|
if (wrapper)
|
||||||
|
wrapper.style.transform = `rotate(${state.rotations[pageIndex]}deg)`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rotateRightBtn = document.createElement('button');
|
||||||
|
rotateRightBtn.className =
|
||||||
|
'rotate-right-btn flex items-center gap-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 text-white rounded border border-gray-600 text-xs cursor-pointer';
|
||||||
|
rotateRightBtn.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
state.rotations[pageIndex] = state.rotations[pageIndex] + 90;
|
||||||
|
const wrapper = container.querySelector(
|
||||||
|
'.thumbnail-wrapper'
|
||||||
|
) as HTMLElement;
|
||||||
|
if (wrapper)
|
||||||
|
wrapper.style.transform = `rotate(${state.rotations[pageIndex]}deg)`;
|
||||||
|
});
|
||||||
|
|
||||||
|
controls.append(rotateLeftBtn, rotateRightBtn);
|
||||||
|
container.appendChild(controls);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
function batchRotateAll(
|
||||||
|
state: RotateState,
|
||||||
|
angle: number,
|
||||||
|
containers: HTMLElement[]
|
||||||
|
) {
|
||||||
|
for (let i = 0; i < state.rotations.length; i++) {
|
||||||
|
state.rotations[i] = state.rotations[i] + angle;
|
||||||
|
}
|
||||||
|
for (const container of containers) {
|
||||||
|
const idx = parseInt(container.dataset.pageIndex!, 10);
|
||||||
|
const wrapper = container.querySelector(
|
||||||
|
'.thumbnail-wrapper'
|
||||||
|
) as HTMLElement;
|
||||||
|
if (wrapper) wrapper.style.transform = `rotate(${state.rotations[idx]}deg)`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('rotate-pdf-page – page wrapper', () => {
|
||||||
|
let parentContainer: HTMLElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
parentContainer = document.createElement('div');
|
||||||
|
parentContainer.id = 'page-thumbnails';
|
||||||
|
document.body.appendChild(parentContainer);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a page wrapper with correct data attributes', () => {
|
||||||
|
const state = createTestState(3);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
expect(wrapper.dataset.pageIndex).toBe('0');
|
||||||
|
expect(wrapper.dataset.pageNumber).toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have left and right rotation buttons', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn');
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn');
|
||||||
|
expect(leftBtn).not.toBeNull();
|
||||||
|
expect(rightBtn).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rotate right by 90° on right-button click', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
rightBtn.click();
|
||||||
|
|
||||||
|
expect(state.rotations[0]).toBe(90);
|
||||||
|
const tw = wrapper.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
expect(tw.style.transform).toBe('rotate(90deg)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should rotate left by -90° on left-button click', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn') as HTMLElement;
|
||||||
|
leftBtn.click();
|
||||||
|
|
||||||
|
expect(state.rotations[0]).toBe(-90);
|
||||||
|
const tw = wrapper.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
expect(tw.style.transform).toBe('rotate(-90deg)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remain functional after multiple right-button clicks', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(90);
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(180);
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(270);
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(360);
|
||||||
|
|
||||||
|
const tw = wrapper.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
expect(tw.style.transform).toBe('rotate(360deg)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remain functional after multiple left-button clicks', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn') as HTMLElement;
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-90);
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-180);
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-270);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow alternating left and right clicks', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn') as HTMLElement;
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
rightBtn.click();
|
||||||
|
leftBtn.click();
|
||||||
|
rightBtn.click();
|
||||||
|
leftBtn.click();
|
||||||
|
leftBtn.click();
|
||||||
|
|
||||||
|
expect(state.rotations[0]).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should independently rotate different pages', () => {
|
||||||
|
const state = createTestState(3);
|
||||||
|
const w1 = createPageWrapper(1, state);
|
||||||
|
const w2 = createPageWrapper(2, state);
|
||||||
|
const w3 = createPageWrapper(3, state);
|
||||||
|
parentContainer.append(w1, w2, w3);
|
||||||
|
|
||||||
|
(w1.querySelector('.rotate-right-btn') as HTMLElement).click();
|
||||||
|
(w2.querySelector('.rotate-left-btn') as HTMLElement).click();
|
||||||
|
|
||||||
|
expect(state.rotations).toEqual([90, -90, 0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow per-page rotation after a batch rotation', () => {
|
||||||
|
const state = createTestState(3);
|
||||||
|
const w1 = createPageWrapper(1, state);
|
||||||
|
const w2 = createPageWrapper(2, state);
|
||||||
|
const w3 = createPageWrapper(3, state);
|
||||||
|
parentContainer.append(w1, w2, w3);
|
||||||
|
|
||||||
|
batchRotateAll(state, 90, [w1, w2, w3]);
|
||||||
|
expect(state.rotations).toEqual([90, 90, 90]);
|
||||||
|
|
||||||
|
const rightBtn = w1.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(180);
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(270);
|
||||||
|
|
||||||
|
expect(state.rotations[1]).toBe(90);
|
||||||
|
expect(state.rotations[2]).toBe(90);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow per-page rotation after multiple batch rotations', () => {
|
||||||
|
const state = createTestState(2);
|
||||||
|
const w1 = createPageWrapper(1, state);
|
||||||
|
const w2 = createPageWrapper(2, state);
|
||||||
|
parentContainer.append(w1, w2);
|
||||||
|
|
||||||
|
batchRotateAll(state, 90, [w1, w2]);
|
||||||
|
batchRotateAll(state, 90, [w1, w2]);
|
||||||
|
|
||||||
|
expect(state.rotations).toEqual([180, 180]);
|
||||||
|
|
||||||
|
(w1.querySelector('.rotate-left-btn') as HTMLElement).click();
|
||||||
|
expect(state.rotations[0]).toBe(90);
|
||||||
|
|
||||||
|
(w1.querySelector('.rotate-left-btn') as HTMLElement).click();
|
||||||
|
expect(state.rotations[0]).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow batch rotation after per-page rotation', () => {
|
||||||
|
const state = createTestState(2);
|
||||||
|
const w1 = createPageWrapper(1, state);
|
||||||
|
const w2 = createPageWrapper(2, state);
|
||||||
|
parentContainer.append(w1, w2);
|
||||||
|
|
||||||
|
(w1.querySelector('.rotate-right-btn') as HTMLElement).click();
|
||||||
|
expect(state.rotations[0]).toBe(90);
|
||||||
|
|
||||||
|
batchRotateAll(state, -90, [w1, w2]);
|
||||||
|
expect(state.rotations).toEqual([0, -90]);
|
||||||
|
|
||||||
|
(w2.querySelector('.rotate-right-btn') as HTMLElement).click();
|
||||||
|
expect(state.rotations[1]).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply correct CSS transform on each click', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const tw = wrapper.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
expect(tw.style.transform).toBe('rotate(0deg)');
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(tw.style.transform).toBe('rotate(90deg)');
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(tw.style.transform).toBe('rotate(180deg)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should apply initial rotation from state', () => {
|
||||||
|
const state = createTestState(2);
|
||||||
|
state.rotations[0] = 180;
|
||||||
|
state.rotations[1] = -90;
|
||||||
|
|
||||||
|
const w1 = createPageWrapper(1, state);
|
||||||
|
const w2 = createPageWrapper(2, state);
|
||||||
|
|
||||||
|
const tw1 = w1.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
const tw2 = w2.querySelector('.thumbnail-wrapper') as HTMLElement;
|
||||||
|
|
||||||
|
expect(tw1.style.transform).toBe('rotate(180deg)');
|
||||||
|
expect(tw2.style.transform).toBe('rotate(-90deg)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should stop click propagation on rotation buttons', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const parentClickSpy = vi.fn();
|
||||||
|
wrapper.addEventListener('click', parentClickSpy);
|
||||||
|
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
rightBtn.click();
|
||||||
|
|
||||||
|
expect(parentClickSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have cursor-pointer class on rotation buttons', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn') as HTMLElement;
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
expect(leftBtn.classList.contains('cursor-pointer')).toBe(true);
|
||||||
|
expect(rightBtn.classList.contains('cursor-pointer')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle rapid successive clicks without losing state', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
for (let i = 0; i < 20; i++) {
|
||||||
|
rightBtn.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(state.rotations[0]).toBe(20 * 90);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep working even if button innerHTML is replaced (simulating createIcons)', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const rightBtn = wrapper.querySelector('.rotate-right-btn') as HTMLElement;
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(90);
|
||||||
|
|
||||||
|
rightBtn.innerHTML = '<svg class="w-3 h-3"></svg>';
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(180);
|
||||||
|
|
||||||
|
rightBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(270);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep working after replaceChild on icon element inside button', () => {
|
||||||
|
const state = createTestState(1);
|
||||||
|
const wrapper = createPageWrapper(1, state);
|
||||||
|
parentContainer.appendChild(wrapper);
|
||||||
|
|
||||||
|
const leftBtn = wrapper.querySelector('.rotate-left-btn') as HTMLElement;
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-90);
|
||||||
|
|
||||||
|
const oldChild = leftBtn.firstChild;
|
||||||
|
if (oldChild) {
|
||||||
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
|
svg.setAttribute('class', 'w-3 h-3');
|
||||||
|
leftBtn.replaceChild(svg, oldChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-180);
|
||||||
|
|
||||||
|
leftBtn.click();
|
||||||
|
expect(state.rotations[0]).toBe(-270);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user