From cdcd4df298db95849b9705b84931722c10cc6d18 Mon Sep 17 00:00:00 2001 From: Mikhail Zhirnov Date: Thu, 14 Sep 2023 15:33:10 +0300 Subject: [PATCH 1/4] - added 1 test to 'erase-tool'; - added expected snapshots; - added 'Promise' to formats.ts --- .../Erase-Tool/erase-tool.spec.ts | 28 +++++++++++- ...bar-icon-verification-1-chromium-linux.png | Bin 0 -> 6716 bytes .../tests/utils/formats/formats.ts | 43 ++++++++++++------ 3 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts-snapshots/Erase-Tool-Toolbar-icon-verification-1-chromium-linux.png diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts index 60b851ba7f..0742dae422 100644 --- a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts +++ b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts @@ -1,5 +1,10 @@ import { expect, test } from '@playwright/test'; -import { selectAction, selectTool, takeEditorScreenshot } from '@utils/canvas'; +import { + selectAction, + selectTool, + takeEditorScreenshot, + takeLeftToolbarScreenshot, +} from '@utils/canvas'; import { getLeftAtomByAttributes } from '@utils/canvas/atoms'; import { getLeftBondByAttributes } from '@utils/canvas/bonds'; import { BondType } from '@utils/canvas/types'; @@ -145,3 +150,24 @@ test.describe('Erase Tool', () => { expect(arrowOnCanvas).toEqual(reactionArrow); }); }); + +test.describe('Erase Tool', () => { + test.beforeEach(async ({ page }) => { + await waitForPageInit(page); + }); + + test.afterEach(async ({ page }) => { + await takeLeftToolbarScreenshot(page); + }); + + test('Toolbar icon verification', async ({ page }) => { + /* + Test case: EPMLSOPKET-1362 + Description: The appropriate icon presents at the Toolbar for Erase tool. + */ + await openFileAndAddToCanvas( + 'Rxn-V2000/benzene-bromobutane-reaction.rxn', + page, + ); + }); +}); diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts-snapshots/Erase-Tool-Toolbar-icon-verification-1-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Erase-Tool/erase-tool.spec.ts-snapshots/Erase-Tool-Toolbar-icon-verification-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..1c662d78782c929c60396da1fca4eb5b9c247cab GIT binary patch literal 6716 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 literal 0 HcmV?d00001 diff --git a/ketcher-autotests/tests/utils/formats/formats.ts b/ketcher-autotests/tests/utils/formats/formats.ts index 7df76107f9..66623a2a74 100644 --- a/ketcher-autotests/tests/utils/formats/formats.ts +++ b/ketcher-autotests/tests/utils/formats/formats.ts @@ -1,76 +1,91 @@ import { Page } from '@playwright/test'; import { MolfileFormat } from 'ketcher-core'; -export async function getKet(page: Page) { +export async function getKet(page: Page): Promise { return await page.evaluate(() => window.ketcher.getKet()); } -export async function getCml(page: Page) { +export async function getCml(page: Page): Promise { return await page.evaluate(() => window.ketcher.getCml()); } -export async function getCdxml(page: Page) { +export async function getCdxml(page: Page): Promise { return await page.evaluate(() => window.ketcher.getCDXml()); } -export async function getSmiles(page: Page) { +export async function getSmiles(page: Page): Promise { return await page.evaluate(() => window.ketcher.getSmiles()); } -export async function getInchi(page: Page) { +export async function getInchi(page: Page): Promise { return await page.evaluate(() => window.ketcher.getInchi()); } -export async function getExtendedSmiles(page: Page) { +export async function getExtendedSmiles(page: Page): Promise { return await page.evaluate(() => window.ketcher.getSmiles(true)); } -export async function getMolfile(page: Page, fileFormat?: MolfileFormat) { +export async function getMolfile( + page: Page, + fileFormat?: MolfileFormat, +): Promise { return await page.evaluate( (fileFormat) => window.ketcher.getMolfile(fileFormat), fileFormat, ); } -export async function getRxn(page: Page, fileFormat?: MolfileFormat) { +export async function getRxn( + page: Page, + fileFormat?: MolfileFormat, +): Promise { return await page.evaluate( (fileFormat) => window.ketcher.getRxn(fileFormat), fileFormat, ); } -export async function getSmarts(page: Page) { +export async function getSmarts(page: Page): Promise { return await page.evaluate(() => window.ketcher.getSmarts()); } -export async function getSdf(page: Page, fileFormat: MolfileFormat = 'v2000') { +export async function getSdf( + page: Page, + fileFormat: MolfileFormat = 'v2000', +): Promise { return await page.evaluate( (fileFormat) => window.ketcher.getSdf(fileFormat), fileFormat, ); } -export async function setMolecule(page: Page, structStr: string) { +export async function setMolecule( + page: Page, + structStr: string, +): Promise { return await page.evaluate( (structStr) => window.ketcher.setMolecule(structStr), structStr, ); } -export async function addFragment(page: Page, structStr: string) { +export async function addFragment( + page: Page, + structStr: string, +): Promise { return await page.evaluate( (structStr) => window.ketcher.setMolecule(structStr), structStr, ); } -export async function enableDearomatizeOnLoad(page: Page) { +export async function enableDearomatizeOnLoad(page: Page): Promise { return await page.evaluate(() => window.ketcher.setSettings({ 'general.dearomatize-on-load': 'true' }), ); } -export async function disableQueryElements(page: Page) { +export async function disableQueryElements(page: Page): Promise { return await page.evaluate(() => { return window.ketcher.setSettings({ // TODO fix types for setSettings in Ketcher-core From 7f331a540f9f61e8e5c3d1cd97f8ff5f707f8add Mon Sep 17 00:00:00 2001 From: Mikhail Zhirnov Date: Fri, 15 Sep 2023 16:32:14 +0300 Subject: [PATCH 2/4] - added 3 tests to 'layout-tool'; - added expected snapshots; - added 2 test files --- .../Layout/layout-tool.spec.ts | 54 ++ ...n-after-clicks-Ctrl-L-1-chromium-linux.png | Bin 0 -> 6329 bytes ...-clicks-Layout-button-1-chromium-linux.png | Bin 0 -> 8801 bytes ...-clicks-Layout-button-1-chromium-linux.png | Bin 0 -> 20431 bytes .../test-data/KET/two-atoms-and-bond.ket | 71 +++ ...-templates-rings-and-functional-groups.ket | 538 ++++++++++++++++++ 6 files changed, 663 insertions(+) create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-Molecular-structures-are-displayed-in-the-middle-of-the-screen-after-clicks-Ctrl-L-1-chromium-linux.png create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-Structures-are-displayed-in-the-middle-of-the-screen-after-clicks-Layout-button-1-chromium-linux.png create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-The-reaction-is-displayed-in-the-middle-of-the-screen-after-clicks-Layout-button-1-chromium-linux.png create mode 100644 ketcher-autotests/tests/test-data/KET/two-atoms-and-bond.ket create mode 100644 ketcher-autotests/tests/test-data/KET/two-templates-rings-and-functional-groups.ket diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts new file mode 100644 index 0000000000..48b19e6aa7 --- /dev/null +++ b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts @@ -0,0 +1,54 @@ +import { test } from '@playwright/test'; +import { + selectTopPanelButton, + openFileAndAddToCanvas, + TopPanelButton, + takeEditorScreenshot, + waitForPageInit, +} from '@utils'; + +test.describe('Layout', () => { + test.beforeEach(async ({ page }) => { + await waitForPageInit(page); + }); + + test.afterEach(async ({ page }) => { + await takeEditorScreenshot(page); + }); + + test('Structures are displayed in the middle of the screen after clicks "Layout" button', async ({ + page, + }) => { + /* + Test case: EPMLSOPKET-16884 + Description: The structures are displayed orderly in the middle of the screen + */ + await openFileAndAddToCanvas('KET/calculated-values-chain.ket', page); + await selectTopPanelButton(TopPanelButton.Layout, page); + }); + + test('Molecular structures are displayed in the middle of the screen after clicks "Ctrl+L"', async ({ + page, + }) => { + /* + Test case: EPMLSOPKET-16885 + Description: The structures are displayed orderly in the middle of the screen + */ + await openFileAndAddToCanvas('KET/two-atoms-and-bond.ket', page); + await page.keyboard.press('Control+l'); + }); + + test('The reaction is displayed in the middle of the screen after clicks "Layout" button', async ({ + page, + }) => { + /* + Test case: EPMLSOPKET-16886 + Description: The structures are displayed orderly in the middle of the screen + */ + await openFileAndAddToCanvas( + 'KET/two-templates-rings-and-functional-groups.ket', + page, + ); + await selectTopPanelButton(TopPanelButton.Layout, page); + }); +}); diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-Molecular-structures-are-displayed-in-the-middle-of-the-screen-after-clicks-Ctrl-L-1-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-Molecular-structures-are-displayed-in-the-middle-of-the-screen-after-clicks-Ctrl-L-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b92fe0569efe6ca5284e5aaab35c719575cbdcbf GIT binary patch literal 6329 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 bLzS_<)lae4zfNGmZ3XS>dA#=fz^nfTm|~E# literal 0 HcmV?d00001 diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-The-reaction-is-displayed-in-the-middle-of-the-screen-after-clicks-Layout-button-1-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Layout/layout-tool.spec.ts-snapshots/Layout-The-reaction-is-displayed-in-the-middle-of-the-screen-after-clicks-Layout-button-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..198dde4e728b159fd63e1f334f0a8de87dc1de8b GIT binary patch literal 20431 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�xUu7bw?AycyH+9vK$4LQO2|Ui z_p3T21mryuyf7{{wgeN2d*_UQI1`DT6S9>cgtMOjNkaeMqXFfA7e@a5#s4qB`QKgr zcUS){WP)h_M>)^GW%Yl3SsA2)w>%D}nxn+V#_IQN!yVKAa}C`Xm%R|1Nvk(8e^XAg zyajXp{xPbwAqn3~u}wN`Ql4pI_5!0MnakC^=P~2*?#cUA>iSiGs-8EqRix#LU6Q_- JeE#}_{{cq`8@>Pl literal 0 HcmV?d00001 diff --git a/ketcher-autotests/tests/test-data/KET/two-atoms-and-bond.ket b/ketcher-autotests/tests/test-data/KET/two-atoms-and-bond.ket new file mode 100644 index 0000000000..6a9a98d9bb --- /dev/null +++ b/ketcher-autotests/tests/test-data/KET/two-atoms-and-bond.ket @@ -0,0 +1,71 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 1.4500000000000002, + -2.0500000000000003, + 0 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "O", + "location": [ + 22, + -7.875, + 0 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 3.266987298107781, + -13.5, + 0 + ] + }, + { + "label": "C", + "location": [ + 4.13301270189222, + -13, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + } + ] + } +} \ No newline at end of file diff --git a/ketcher-autotests/tests/test-data/KET/two-templates-rings-and-functional-groups.ket b/ketcher-autotests/tests/test-data/KET/two-templates-rings-and-functional-groups.ket new file mode 100644 index 0000000000..e1256f94a1 --- /dev/null +++ b/ketcher-autotests/tests/test-data/KET/two-templates-rings-and-functional-groups.ket @@ -0,0 +1,538 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + }, + { + "$ref": "mol1" + }, + { + "$ref": "mol2" + }, + { + "$ref": "mol3" + }, + { + "$ref": "mol4" + }, + { + "$ref": "mol5" + }, + { + "type": "arrow", + "data": { + "mode": "open-angle", + "pos": [ + { + "x": 4.375, + "y": -13.175, + "z": 0 + }, + { + "x": 7.82943555447196, + "y": -13.175, + "z": 0 + } + ] + } + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 1.8348491521285664, + -12.675074417174608, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.5651508478714344, + -12.674589229177204, + 0 + ] + }, + { + "label": "C", + "location": [ + 2.7016375094912393, + -12.174966888850188, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.5651508478714344, + -13.675532067822148, + 0 + ] + }, + { + "label": "C", + "location": [ + 1.8348491521285664, + -13.680020056798138, + 0 + ] + }, + { + "label": "C", + "location": [ + 2.7038208554795586, + -14.175033111149814, + 0 + ] + } + ], + "bonds": [ + { + "type": 2, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 2, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + } + ] + }, + "mol1": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 20.17505003874321, + -1.7049537807495008, + 0 + ] + }, + { + "label": "C", + "location": [ + 20.67543747083789, + -3.2450462192504994, + 0 + ] + }, + { + "label": "C", + "location": [ + 20.984676903872398, + -2.2988135851594644, + 0 + ] + }, + { + "label": "C", + "location": [ + 19.674662606648532, + -3.2450462192504994, + 0 + ] + }, + { + "label": "C", + "location": [ + 19.365323096127604, + -2.2988135851594644, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 2, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 3 + ] + } + ] + }, + "mol2": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 8.534849152128567, + -12.675074417174608, + 0 + ] + }, + { + "label": "C", + "location": [ + 10.265150847871434, + -12.674589229177204, + 0 + ] + }, + { + "label": "C", + "location": [ + 9.40163750949124, + -12.174966888850188, + 0 + ] + }, + { + "label": "C", + "location": [ + 10.265150847871434, + -13.675532067822148, + 0 + ] + }, + { + "label": "C", + "location": [ + 8.534849152128567, + -13.680020056798138, + 0 + ] + }, + { + "label": "C", + "location": [ + 9.403820855479559, + -14.175033111149812, + 0 + ] + } + ], + "bonds": [ + { + "type": 2, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 2, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + } + ] + }, + "mol3": { + "type": "molecule", + "atoms": [ + { + "label": "N", + "location": [ + 6.125, + -12.700000000000001, + 0 + ] + } + ] + }, + "mol4": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 1.925, + -1.975, + 0 + ] + }, + { + "label": "O", + "location": [ + 2.4250036667338906, + -1.108993649216902, + 0 + ] + }, + { + "label": "O", + "location": [ + 2.4250036667338906, + -2.8410063507830983, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.425011000201671, + -1.108993649216902, + 0 + ] + }, + { + "label": "C", + "location": [ + 4.425018333669453, + -1.108993649216902, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.425011000201671, + -0.10898631574912088, + 0 + ] + }, + { + "label": "C", + "location": [ + 3.425011000201671, + -2.109000982684683, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 2, + "atoms": [ + 0, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 3 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 3, + 6 + ] + } + ], + "sgroups": [ + { + "type": "SUP", + "atoms": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "name": "Boc", + "id": 0, + "attachmentPoints": [ + { + "attachmentAtom": 0, + "attachmentId": "" + } + ] + } + ] + }, + "mol5": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 18.275000000000002, + -13.205000019073488, + 0 + ] + }, + { + "label": "Cl", + "location": [ + 18.275000000000002, + -12.281100491592762, + 0 + ] + }, + { + "label": "Cl", + "location": [ + 19.322749316090526, + -13.205000019073488, + 0 + ] + }, + { + "label": "Cl", + "location": [ + 17.246648843571254, + -13.205000019073488, + 0 + ] + } + ], + "bonds": [ + { + "type": 1, + "atoms": [ + 0, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 2 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 3 + ] + } + ], + "sgroups": [ + { + "type": "SUP", + "atoms": [ + 0, + 1, + 2, + 3 + ], + "name": "CCl3", + "expanded": true, + "id": 0, + "attachmentPoints": [ + { + "attachmentAtom": 0, + "attachmentId": "" + } + ] + } + ] + } +} \ No newline at end of file From 6f03084f908eeec66e4a76b0ae4553ec1597ed97 Mon Sep 17 00:00:00 2001 From: Mikhail Zhirnov Date: Sat, 16 Sep 2023 10:35:33 +0300 Subject: [PATCH 3/4] - added tests; - added expected screenshots --- ketcher-autotests/package.json | 2 +- .../Track-Changes/track-changes.spec.ts | 91 ++++++++++++++++++ ...teps-Undo-Redo-action-1-chromium-linux.png | Bin 0 -> 6033 bytes ...teps-Undo-Redo-action-2-chromium-linux.png | Bin 0 -> 11796 bytes package-lock.json | 64 ++++++------ 5 files changed, 124 insertions(+), 33 deletions(-) create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-1-chromium-linux.png create mode 100644 ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-2-chromium-linux.png diff --git a/ketcher-autotests/package.json b/ketcher-autotests/package.json index bdeac19ab2..7fed4b36b6 100644 --- a/ketcher-autotests/package.json +++ b/ketcher-autotests/package.json @@ -24,7 +24,7 @@ "author": "Nitvex", "license": "ISC", "devDependencies": { - "@playwright/test": "1.37.0", + "@playwright/test": "^1.37.0", "eslint": "^8.44.0", "lint-staged": "^13.1.2", "prettier": "2.8.4" diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts new file mode 100644 index 0000000000..cd38155c8b --- /dev/null +++ b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts @@ -0,0 +1,91 @@ +import { test } from '@playwright/test'; +import { + selectTopPanelButton, + TopPanelButton, + takeEditorScreenshot, + waitForPageInit, + selectAtomInToolbar, + AtomButton, +} from '@utils'; + +test.describe('Track Changes', () => { + test.beforeEach(async ({ page }) => { + await waitForPageInit(page); + }); + + test('Track 32 steps (Undo,Redo action)', async ({ page }) => { + /* + Test case: EPMLSOPKET-1989 + Description: Add Nitrogen atom to canvas 32 times and then press Undo 32 times + */ + + const atomType = AtomButton.Nitrogen; + + // Function to add an atom at specific coordinates + const addAtom = async (x: number, y: number) => { + await selectAtomInToolbar(atomType, page); + await page.mouse.click(x, y); + }; + + // Define an array of coordinates + const coordinates = [ + { x: 100, y: 100 }, + { x: 150, y: 150 }, + { x: 200, y: 200 }, + { x: 250, y: 250 }, + { x: 300, y: 300 }, + { x: 350, y: 350 }, + { x: 400, y: 400 }, + { x: 450, y: 450 }, + { x: 500, y: 500 }, + { x: 500, y: 550 }, + { x: 650, y: 600 }, + { x: 600, y: 650 }, + { x: 750, y: 700 }, + { x: 700, y: 750 }, + { x: 800, y: 800 }, + { x: 850, y: 850 }, + { x: 900, y: 900 }, + { x: 950, y: 950 }, + { x: 100, y: 300 }, + { x: 150, y: 350 }, + { x: 200, y: 400 }, + { x: 250, y: 450 }, + { x: 300, y: 500 }, + { x: 350, y: 550 }, + { x: 400, y: 600 }, + { x: 450, y: 200 }, + { x: 500, y: 350 }, + { x: 550, y: 400 }, + { x: 600, y: 450 }, + { x: 650, y: 500 }, + { x: 700, y: 550 }, + { x: 750, y: 600 }, + { x: 800, y: 200 }, + { x: 800, y: 400 }, + { x: 950, y: 450 }, + { x: 720, y: 500 }, + { x: 650, y: 550 }, + { x: 530, y: 600 }, + { x: 760, y: 200 }, + ]; + + // Add Nitrogen atom to canvas 34 times + for (const { x, y } of coordinates) { + await addAtom(x, y); + } + + // Press Undo 32 times + // eslint-disable-next-line no-magic-numbers + for (let i = 0; i < 32; i++) { + await selectTopPanelButton(TopPanelButton.Undo, page); + } + await takeEditorScreenshot(page); + // Press Redo 32 times + // eslint-disable-next-line no-magic-numbers + for (let i = 0; i < 32; i++) { + await selectTopPanelButton(TopPanelButton.Redo, page); + } + await takeEditorScreenshot(page); + }); +}); diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-1-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..53de308490a3c794a111d2e311951f06569fadae GIT binary patch literal 6033 zcmeHL>syj(8Yk)_mUuQq;U$7qe}Ia0l=J?l5Q5%4(+Gt9*)zUh zhg~btt4S%P@ql!0r6Jd4eteL1w^@|)ch`kK=Qr7SRPDSFv)R$grn}&iy(GEsjs$F; zr}f~8eIXA5ZyYXfu=%t|wC~HkBtKqOQmCjrw>cFXjXe5w;t}5UFK;?|_1>_PHUNv) zb9UzZ&9md!xbVUzC!9M39ndWy5I=1G7{#WOK!p3idW?6ZM9LnxWOoL2%($_;*ffG1TD3qRX+qsOT*@kJcK88K;jOm*E z>?9fAk>-cTw6-d2f5lejX&7ml<%_J+y1oWGP~BjM{4Pmg8UH@dG{{FyqBcQOJ-OWk z5Tg@3b)l7J-REqUf_fSN8=QpPWK+65pb^d%bAx=|r{ddEqL#;mYFrF+(=H$g63nXN z>eu)Cr?C}oWrGp39UruGWjB ziKs;S%)2o4d=nnLsTqnCrhm}p_sm($M)~Uix#6+C^+EPl2ub{7!Z0DPxUg7Ao1t@K zJ1#t|x?0QA8k}@Gv$RIXk#;EG9*1y-KfODmV^|oY26yLvgbV3bwDPv<8 zE%5}tKWs(`UL?l?XK#<#4)mkya4@xr{v(e^@2^J66T$%6e8PWGU%@EnVs75(M7{Ia z9;L02%apoCqhXGoj7fae>2VZA2)gaU&qKcIl`Nu++Z3g-0XBrdO#c)-^os zOoHO|($g>0Fr9u-2kOWr?cemnq{EHmUnVAn%g;S7;V~_3Lc_}ZOS+jP zQzu(`PHdaKakuG;Zknz=NduOGnA!)V`ei+Fa+eGuuQ>&c$6|HD;(BUCubj;oh|-}B4oyKb zA@1jX;Z*RwV*fy~=4z{Dde)S@kXys&T^%X9$G7K6%&Lf~Kv_vTKulq`k50$Dt-HNCO<{MHFryPfCX<_8_Z zV%3L4Vvcvlw|&Or$JN}96@E7TTQUucb#m6#^-0rpR~&mw9;e9$=fsIUofR_J`9Azn zq~E7O+1LyaW`ReUD?fjg>_?ld&{Nd^D5M+H*$R708r7*-%QbM~NW(s%!wib4glaoe z#)tPgc{S}flphE$IiW+iTLlp(aiYl9J0QMJ&ZYAF{)s~V@w7G3rW(|ZOQe;SPjCp1s0nzwuX(-D&VWirv+nW|{7 zl5M7d}T{~tfvHs+Qj>$0O>juTj>B0Lpp;Rvp+l!Jqr zbM4?+S4b;Jev)Qj&a_xQM}PNblzuto(W1-o5c{#M`*m8bBXg4$8L>@~tQ6EM>l}Gq z9K)@@!htgD)$pAys}4a_*6cG5Z!Bxk?cS)QODnoltAkxD>qg)HE1OZtg43snGk$@- Jf>Xrn{{f>&qR{{V literal 0 HcmV?d00001 diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-2-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-2-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..d6113821a7b730a5d285a9315ece77864a0915cd GIT binary patch literal 11796 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 LCP#CBv%mI#TIJ-< literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index f80dda0283..5a191e49c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -803,31 +803,12 @@ "ketcher-core": "*" }, "devDependencies": { - "@playwright/test": "1.37.0", + "@playwright/test": "^1.37.0", "eslint": "^8.44.0", "lint-staged": "^13.1.2", "prettier": "2.8.4" } }, - "ketcher-autotests/node_modules/@playwright/test": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", - "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "playwright-core": "1.37.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, "ketcher-autotests/node_modules/chalk": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", @@ -1052,18 +1033,6 @@ "node": ">=0.10" } }, - "ketcher-autotests/node_modules/playwright-core": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", - "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", - "dev": true, - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=16" - } - }, "ketcher-autotests/node_modules/prettier": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", @@ -4608,6 +4577,25 @@ "node": ">= 8" } }, + "node_modules/@playwright/test": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.0.tgz", + "integrity": "sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "playwright-core": "1.37.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.4", "license": "MIT", @@ -17881,6 +17869,18 @@ "node": ">=4" } }, + "node_modules/playwright-core": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.0.tgz", + "integrity": "sha512-1c46jhTH/myQw6sesrcuHVtLoSNfJv8Pfy9t3rs6subY7kARv0HRw5PpyfPYPpPtQvBOmgbE6K+qgYUpj81LAA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/playwright-testing": { "resolved": "ketcher-autotests", "link": true From f666b02379b0289c96f051368bc2797d618572cd Mon Sep 17 00:00:00 2001 From: Mikhail Zhirnov Date: Mon, 18 Sep 2023 16:28:05 +0300 Subject: [PATCH 4/4] - code refactoring; - updated snapshots --- .../Track-Changes/track-changes.spec.ts | 67 +++++------------- ...teps-Undo-Redo-action-1-chromium-linux.png | Bin 6033 -> 6265 bytes ...teps-Undo-Redo-action-2-chromium-linux.png | Bin 11796 -> 9299 bytes 3 files changed, 16 insertions(+), 51 deletions(-) diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts index cd38155c8b..f7d89f2cab 100644 --- a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts +++ b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts @@ -16,74 +16,39 @@ test.describe('Track Changes', () => { test('Track 32 steps (Undo,Redo action)', async ({ page }) => { /* Test case: EPMLSOPKET-1989 - Description: Add Nitrogen atom to canvas 32 times and then press Undo 32 times + Description: Add Nitrogen atom to canvas 35 times and then press Undo 32 times */ const atomType = AtomButton.Nitrogen; - // Function to add an atom at specific coordinates const addAtom = async (x: number, y: number) => { await selectAtomInToolbar(atomType, page); await page.mouse.click(x, y); }; - // Define an array of coordinates - const coordinates = [ - { x: 100, y: 100 }, - { x: 150, y: 150 }, - { x: 200, y: 200 }, - { x: 250, y: 250 }, - { x: 300, y: 300 }, - { x: 350, y: 350 }, - { x: 400, y: 400 }, - { x: 450, y: 450 }, - { x: 500, y: 500 }, - { x: 500, y: 550 }, - { x: 650, y: 600 }, - { x: 600, y: 650 }, - { x: 750, y: 700 }, - { x: 700, y: 750 }, - { x: 800, y: 800 }, - { x: 850, y: 850 }, - { x: 900, y: 900 }, - { x: 950, y: 950 }, - { x: 100, y: 300 }, - { x: 150, y: 350 }, - { x: 200, y: 400 }, - { x: 250, y: 450 }, - { x: 300, y: 500 }, - { x: 350, y: 550 }, - { x: 400, y: 600 }, - { x: 450, y: 200 }, - { x: 500, y: 350 }, - { x: 550, y: 400 }, - { x: 600, y: 450 }, - { x: 650, y: 500 }, - { x: 700, y: 550 }, - { x: 750, y: 600 }, - { x: 800, y: 200 }, - { x: 800, y: 400 }, - { x: 950, y: 450 }, - { x: 720, y: 500 }, - { x: 650, y: 550 }, - { x: 530, y: 600 }, - { x: 760, y: 200 }, - ]; + const numberOfRows = 6; + const numberOfColumns = 8; + const step = 100; + const coordinates = []; + + for (let row = 0; row < numberOfRows; row++) { + for (let column = 0; column < numberOfColumns; column++) { + coordinates.push({ x: column * step, y: row * step }); + } + } - // Add Nitrogen atom to canvas 34 times for (const { x, y } of coordinates) { await addAtom(x, y); } - // Press Undo 32 times - // eslint-disable-next-line no-magic-numbers - for (let i = 0; i < 32; i++) { + const maxUndoHistorySize = 32; + for (let i = 0; i < maxUndoHistorySize; i++) { await selectTopPanelButton(TopPanelButton.Undo, page); } await takeEditorScreenshot(page); - // Press Redo 32 times - // eslint-disable-next-line no-magic-numbers - for (let i = 0; i < 32; i++) { + + const maxRedoHistorySize = 32; + for (let i = 0; i < maxRedoHistorySize; i++) { await selectTopPanelButton(TopPanelButton.Redo, page); } await takeEditorScreenshot(page); diff --git a/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-1-chromium-linux.png b/ketcher-autotests/tests/Structure-Creating-&-Editing/Actions-With-Structures/Track-Changes/track-changes.spec.ts-snapshots/Track-Changes-Track-32-steps-Undo-Redo-action-1-chromium-linux.png index 53de308490a3c794a111d2e311951f06569fadae..1a4dc5e8e3eda3797d80fca14bebfb4ed71a302c 100644 GIT binary patch delta 2147 zcmYLKdsNbC8g^`VJf+F(wB@9O>~5B)lVumpGQq8M9d}G>S0GWu$+ZhoObDp3h~}J1 zXT*vcO}tc=7YswCZVyx)7??|Gi{ycdJ# zwqDrE`esLL)ZT>biV5vWBF=*;opiO}0@;dP@$YWRF5ELT@7%<^c3>|d{4#Z!eC3m} zul{mU6}9&G>bQ=)Q&(;r3h2%*t8FR{JfQiCvR_k%-qzN19+d=p#=HAZpGW-x37c;O z#EeH{LQ)v|UjgDlhACCTCVO2(-Si_SUW?&ju}r%);s3aw!+ z7`v4{rnj}Xhr^dGUNXz}lr5g;Z4~N*g5_Y8r%)?YDx=M7G2Qb6od0XrAHb-~uQ`k5Uh`JJTk|&-1WnguI)nxqOX)<14!0vvH;iDJk zq;<6!L!T~c!Xr}jP=BGkh6A*#`GOMdUDgKIC(#9F$j?l$VP9-9Bu+6wb50IGTi#Cc zsUP|~?XT@GP5t?EJ92d-BCJ6cF-62Rr|xxrkm-}dyjS+l?jCb@9AD!ApI=+<3oF}6 z)M2X!o5ebobv+=+z$B=z-iMB)`|c*+K-h&cPtQ8Hd1^VrJXiDg>pxn5TdZKkoStz&O`^l;dUd+pCZ8W<3-&IMZ-_t zCy3KVY5-46km2LgOq7ag!VJtnpn{UfIWfCe9y=`$n*PGg?eCnBom=6bhOMErciCEz z8CB_j>#Ut&ddzA~L09Jz7+4tMKPYO=O$VB>A;LOEO#({A6=KnRv??nG zLZM$~-&q>^W>dbQ>Fq@973?+t9>|ncU@SSNXzKjza|l#ttufPONx{7R9{9QH zg&q5uz{jdgi@RnCg7SZSS<81o1`^tFrQSU*mLA`y7YLnC$6Wz--g+l6tCJ^2lIjLy zM6W$S$POr;bx|nf=FzMy$$LkuB)x-{%M!L$X(C8#>Uc&oLH$H&yImz(K3I$^UN#_VS&(V3~u%L$`$j&1@V?`nJ4^pc;Y9M2`*INKBv;FRt&L zdXV2{H8)|K$Cc+;tC0st<)LuI;yMmOM*46F6DydTX?cM$p3ur4xiuoF0ZKQ$vr|in+&vgm;^08 z$_Y%+Rk=07RZ!)d+gT?_aIeif5f z%bzW&^-?$Dz2oey0w8dxN}#{L@Cf^Q2+m3ydq4&X=`#$7veZR94gJ={)8$NH+fUsX zaQ46Duo*u}zbl4S^SGt5ap<}OOWqd}nrOADBP@FN6 zMR@r!zm0GL&u94?g`qEf2GW;VO>x6fng1oU-CGH3ILVNj8nh!VtRu|`TV|uNlRKcC zH(zC(pGsb0fYM*F9GrN9r$Nx_{dJ;N&@zQPSC$O0og>r@3weKp_x@bE8@WE+(M9PtY~jA$a}C?bZEthm+0UMm^}c)o8bzD`>G%5xx*JVs#7jYy^_b9 jc69`YfZku>x!{+@{bP@8XLl^EL`p@P%57(}%vHo6Ae82BmTeGe(AU@M zIGouM#+u9&ar}h{3Ylms{wy1|Ovw}wU1VH!RS-;_R}vKWrL%wR{pUXS-p}*B_nzmu z&)p0t@&6$JbiMHPxvyewaE)3@c4ZnMU)^ab_F9{pVBc?-7X9F}{+H4==fL`dR}z2Y zzRP*A?6;p%l;?hzjw=arnh5res=IXiSapl@$K_J*FFvJ&3kx%&rPamlIk*JWiLWw_ z3vYe#y+_E%ZKS*f*tk`6u;?E_eJ2-AZs$*X=pL>Z!0Cbnx=x*Om*bUj2mv?3Phzon zBvxU!`wyy=8qKKwuze8sEOcNG+@G!!)jmf?*rx~`VmA9vqBOfrb~0oJ?(wmkN4fnU zz(I%BWBd0xfJ>PW!hd`>HZ)Eq=Zq&K??Z!wF&JQLJX~g0&DbW7pS+B2J}mI?C*mtC zc!D%Lir7mM4XZ$(KC+qoXDzPs&oQUo2R=NC&t1Z!ixdqi5 z?8>Im79^x?L889R6x-&$E3r(7&H2#ACaQCKf9?jAdz%Tf7OP2gAhHuX$(DP4K} zm?xge^SQ)pD>n7tQd7Jvu z;Z>W}tb84zG(9zT*WKI)qvSuNPmxM09#u#f%S=I1-<8Mp*Bga;lZU}zl{Xl8@;>$3 zQ!s~^jGEfZw}S5?E>=EjcAhk3$} zg>u@MKY~IbbBvEtrpEw`we7T&YqmU@AGYYROX*}1ueY9ku0_J+Pue!Q)1?1p z2BUTQTWd>~nI_7b8%tJd$L^ZUSPnD}km7J4a<;N9|61$xyHX@%pmKZvJhlt=B}|v5 zkTYYI7oT#4EL)Gnw6pe#X{E?{G$V^j${SfIDxxV;%FCCV6k9LIJuA2Gw_P(VG4-bz zz*ZznKd-KAgxu3ylk;J%!l769_D7`ktoKAiqb^O&6iEog%`#aAXY~0m!PY9@pM&)Z zY~a?IVmMXll}{G7XJd#soIz62OvjHXIpBD_0ey6G5tc$cEdJc1>^qg;c!lnIw{2;~ zlC@skAQE1mE`K0$70Rp{{Ng1AHxD4E_a@N|k-L;zXOy$LB~jzc5jRaf^VoSfI)%OOAKAK$>_#^N&30vaeP6NO z6pFoS4?%ZX+ch$CzW)`RJC?=Q{&De2O%#*|p2W>Mwz689^wAKzAcRmz~Qt3(k@V0o zz8%p`<~LLZ4(H)%Xd0F08LqjHaG&NXCRV#LhWl$2_WJYqN2$?Uhjs>?$4M)|lY*U} zzsw3}EYuij+J8P`n)5g+S6eRKqe3q*@lq*MVbN0{&BCR-ELRDTt?Tsl$rnJ)N3agL zF=GlpcYw!jByBH%B8plplrfs9OMa||G=q_JxLF6hKtY>EN#>Ftj3bPE3aLbPHJ+-K z&6ZmJV*{T<%?wD4NyDUn6g7FI1KDnSTBV42+69}G({GhBv|Xp=%kb{F=;xh z#R;0$MXSwl^QGlIh#{WEU_fYI*HPboAmm@}upj+ zjp|kAyEik;lAg{uJjUpn!prEvXARvUqE(S0<76J&- zK>?{!LZ}I70v4o*QcOrRp-7FPC6M;s0G1`LZ>{fJ-}`5lzs^l^?>T4hv-k5nd*@!= z>i}E2Xw@PR2()zfzpeL!Knw67(0uf-3xRK>iRH?`FfU|3Y$qtML8A`@S`FH5{l~$G zyF;Cr>x|PWy}WQoNALMYU3&A}k0-!Au0>$+YmVhUdw6QNXHkgVbM_+FZHsko+Z@Z^ zaecA!K#<+;jS2ewVF@O?_h}r?(}*DXtRtPe^~;-+t8X1&uHdTk>mJ4e-RHmS{{DO7 zu!IQ-F|$M&rDdMyeBjDc6d4uiJ7guZ4P@?$%+)oV2V5DV=g-_|b@n&l zERJ%s|4A}9WYF2oS=G8=;YD*Q+$S$msUdj9C2iVaq8MH~`4BFqU zZEKju-I_>x2qb@SpGp+q$fjjP+q8W|;c7G(O0R%gjX&e?+FxD>ZY{nVJe(6wEz@(v z8mFf$C%Q={6-*EF>Z{L1_`bg#5&8bM8j7eWl~i`{R4G!X=qBXK=P4a%^6Ab_v>``J zFkDn~Ab289iM>fBMV*_vnU^VL3Q2=lA{e8{HRn+U`O=Z|g7?o`u1#?V7fh^;wFLIG z_7C2XB?i>-d|2;R$Sc^2K6yd5rDLiSYPF6R z$OEfATsv{NYuVN$UIr_Ai{$O07W!0Oh&44qB}K83ONYSEup#tFjiF<+)Bm*+j3pH#xFy29?5^F>!7b-oI8bqfU4_EKfLTZE{R<)2QkxJ?r6gJ!JM?n{`1h@? zsWfh)I?;{Va)IK@zh8XG@&!Tx*u|dx{+^Nko-XxPXZBYpc-;zdM8hn$KF;pE(ya2? zExT`=>+?)gcN}g97x|k~&I#^a#swWJWY*2R&`W#77O&9AD~_hr0?w_#cJb(hTKn z(=BjHRrjU!Js##OuPno%8L{*$TviodO~YUHG3?Ncb%$&gre}n4grao(i{)+T;P7S6Pix;iSDub31igb zv9YM!d;ga0T6S2g({$txC@c2D1-=$jO~3JSqjc*CsQzb20cFy-$hI?(Xp8BoPpyd* zz3T5P5T(~du;dkJiyOyj7v5%FG)H`xm==a4DFjjNa z!-2t$UBTUNDOiel;86h}XvW4}jJQwbIZrXgm^U2q=wMz%caZT${OQnqwRO|yKRhPs zu;g7jt_Yv>)ejpwSxc3~&=&Xe3ZNS%i03&;pHHpau>g4^s;{~xLW;o{_N1WqqfR!f z2Uy-o5h~OXM5GLMp)pGnY-K^pt$V%k3m6w{(n*PAQw39hFXli}JJoTOk9%{a@~~zD zR9K{E!PguH-|<36n@R#=v7amtZuWDQ$4@{6dgIb$euSw~LUCjpCT?7v{6bDgXFiqAg9IUvj;QxtCyk_U`U*T- zbMTlKad;++ztv)t_i~nohhFcS(K90}g$AbpOF^Lve`>s+GWUO>^lx2TZ2x}|GcqLr z@bKU~(6Q6*0Knlb9;x_oeaYi;+jM7vY5MnR#jLKWj?Z&{t>h?qpbR#38M0dWMC+mK z=@}lDY0B%(H_knxY+~0s@@xB-zA}qgD@Ea~_R*A0m%vw{pZkD$@$znydPCYXiej4P zrZM7doJ`9{98@d_@-P_2m?6Yfxut=9H@0{D)x9e%ki-lMEb=mBr<=sPiYJ+Zrb%MN zRN4AGkB*p-#w^<15MS7bk2vVuS+6az&;ORvt-FVvs*H|4dDci;TFlN;)*)=#>!e6R z2MW6Mv=I#*L^E-*n+SEdd%=mgFLr$vew^m!bA4|TiLPOX98qVE821qPJ^6)y65L`X zv_3r6R$bAi(P}Nzq%m0_G-o36pUH1MQetP2nI~ZOEpXn?tu0kRsY<+fcU`#GT)!Rg8Byt1=BZOgY40i~PyX2Ws54MWh!bgjCt zF0ar{;5O@Jm9j5?uzR{`(qD(n+o3OgaD@7Os$6fT56h|H)@!RYWYfe7upA0Wxy``x zl-}V&)QLAkt>A`$uqC#P;&jDqC<_cRr>HnWU1)Fh!NJ3ai1-kPp|u)fUftYTf%4kK zbYpg1cbh4KcV35($*9UQ)wNffoGdx#>`p{_D@>twpI3pDd9lw_z7UtyYq9{irYeB00Ab9nRLy0Tn}M zO$ffgcRsZ}ly%WHD#Wst(GhoL>*T`QyxF4uD-XswlV8(ny00T4 z$AF=oV4yR{d4FFtYB^=C?7}caofNDg1W--2PIMEBW4})o(B?>bG>8LKWlzo!OQj!T z#`z`e@`teDV|I5G;>$ZDpO(G4Ruhxlx&<-b8^zhx+s5we%_@yNuG3(dtrF7kNb^z} zR5Eu~0JW=nYLAbXil%Hgcm#DR-TuBmMBXveAG%41iP`4U#vW_&<&6g1R=Q_Y_{FYS z!5s&K$)_LiX+?A#x8!x7euc*{lPNE@M*A8}32g%*W@b|lyj$a9Y(}qe{Ytd8&QxMG zFF4hwaJqbQejrS55NgH-tb&6rlU~KhoAxlkK@5+swk zPX3)*!Og$u$H0oysAbG_kv` zz@Wplp{INTS$}6{+*y*D{1t5P^sOMv-7Iqa;sJKff>j zfVcU)RdYb4+VwQbGmCGXj*Qi#}Gy3WRO&n{)6(?GJ(n-~C;tKwm;Dc^(n4t}3NA73~zl+V6H2Nz5xez2=1 zEj`F<$7SK8)9p&>HQ$n?tmzU;$fKNJr_H7-5ZS}X5=2|-dff@w29LcsKWK;2cwQrN z=;-&tx;%Ck6xy!KROG)Efxp%NF+({wi3q$YFi-X_z(2^WpQikig7oKU{tu_wmz$LZ zyeFd}?@M&6Pyo7uXSXWi&jv>staoypmd96qW99V9L%wA(Sk7LZZk(HSR$L%4; kWJ;usmw>YHY~Uv;=t11?ItG1sy3E(RZ5*ugc6y%w530K~-2eap literal 11796 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 LCP#CBv%mI#TIJ-<