Skip to content

Commit

Permalink
#4495 - Macro: UI support for IDT import/export
Browse files Browse the repository at this point in the history
  • Loading branch information
ilya-asiyuk-epam committed Apr 29, 2024
1 parent 65a15fa commit e2fd5c9
Show file tree
Hide file tree
Showing 19 changed files with 171 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { test, expect } from '@playwright/test';
import {
TopPanelButton,
openFileAndAddToCanvasMacro,
selectTopPanelButton,
takeEditorScreenshot,
waitForPageInit,
saveToFile,
openFile,
receiveFileComparisonData,
// selectOptionInDropdown,
// pressButton,
chooseFileFormat,
readFileContents,
// moveMouseAway,
getIdt,
} from '@utils';
import { turnOnMacromoleculesEditor } from '@utils/macromolecules';

function removeNotComparableData(file: string) {
return file.replaceAll('\r', '');
}
test.describe('Import-Saving .idt Files', () => {
test.beforeEach(async ({ page }) => {
await waitForPageInit(page);
await turnOnMacromoleculesEditor(page);
});

// TODO: uncomment after solving Indigo issue
// test(`Import .idt file`, async ({ page }) => {
// await openFileAndAddToCanvasMacro('IDT/idt-rna-a.idt', page);
// await moveMouseAway(page);
// await takeEditorScreenshot(page);
// });

// TODO: uncomment after solving Indigo issue
// test('Import incorrect data', async ({ page }) => {
// const randomText = '!+%45#asjfnsalkfl';
// await selectTopPanelButton(TopPanelButton.Open, page);
// await page.getByTestId('paste-from-clipboard-button').click();
// await page.getByTestId('open-structure-textarea').fill(randomText);
// await chooseFileFormat(page, 'IDT');
// await page.getByTestId('add-to-canvas-button').click();
// await takeEditorScreenshot(page);
// });

test('Check import of .ket file and save in .idt format', async ({
page,
}) => {
await openFileAndAddToCanvasMacro('KET/rna-a.ket', page);
const expectedFile = await getIdt(page);
await saveToFile('IDT/idt-rna-a-expected.idt', expectedFile);

const METADATA_STRING_INDEX = [1];

const { fileExpected: idtFileExpected, file: idtFile } =
await receiveFileComparisonData({
page,
expectedFileName: 'tests/test-data/IDT/idt-rna-a-expected.idt',
metaDataIndexes: METADATA_STRING_INDEX,
});

expect(idtFile).toEqual(idtFileExpected);

await takeEditorScreenshot(page);
});

test('Check that empty file can be saved in .idt format', async ({
page,
}) => {
const expectedFile = await getIdt(page);
await saveToFile('IDT/idt-empty.idt', expectedFile);

const METADATA_STRING_INDEX = [1];

const { fileExpected: idtFileExpected, file: idtFile } =
await receiveFileComparisonData({
page,
expectedFileName: 'tests/test-data/IDT/idt-empty.idt',
metaDataIndexes: METADATA_STRING_INDEX,
});

expect(idtFile).toEqual(idtFileExpected);
});

test('Check that system does not let importing empty .idt file', async ({
page,
}) => {
await selectTopPanelButton(TopPanelButton.Open, page);
await openFile('IDT/idt-empty.idt', page);
await page.getByText('Add to Canvas').isDisabled();
});

// TODO: uncomment after solving Indigo issue
// test('Check that system does not let uploading corrupted .idt file', async ({
// page,
// }) => {
// await selectTopPanelButton(TopPanelButton.Open, page);
//
// const filename = 'IDT/idt-corrupted.idt';
// await openFile(filename, page);
// await selectOptionInDropdown(filename, page);
// await pressButton(page, 'Add to Canvas');
// await takeEditorScreenshot(page);
// });

test('Should open .ket file and modify to .idt format in save modal textarea', async ({
page,
}) => {
await openFileAndAddToCanvasMacro('KET/rna-a.ket', page);
await selectTopPanelButton(TopPanelButton.Save, page);
await chooseFileFormat(page, 'IDT');
await page
.getByTestId('dropdown-select')
.getByRole('combobox')
.allInnerTexts();

const textArea = page.getByTestId('preview-area-text');
const file = await readFileContents('tests/test-data/IDT/idt-rna-a.idt');
const expectedData = removeNotComparableData(file);
const valueInTextarea = removeNotComparableData(
await textArea.inputValue(),
);
expect(valueInTextarea).toBe(expectedData);
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions ketcher-autotests/tests/test-data/IDT/idt-corrupted.idt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!+-$#12w12r23e32e33
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rA/3Phos/
1 change: 1 addition & 0 deletions ketcher-autotests/tests/test-data/IDT/idt-rna-a.idt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rA/3Phos/
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const GetFileMethod: Record<string, keyof Ketcher> = {
sdf: 'getSdf',
fasta: 'getFasta',
seq: 'getSequence',
idt: 'getIdt',
} as const;

type KetcherApiFunction = (format?: string) => Promise<string>;
Expand Down
4 changes: 4 additions & 0 deletions ketcher-autotests/tests/utils/formats/formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export async function getFasta(page: Page): Promise<string> {
return await page.evaluate(() => window.ketcher.getFasta());
}

export async function getIdt(page: Page): Promise<string> {
return await page.evaluate(() => window.ketcher.getIdt());
}

export async function getSequence(page: Page): Promise<string> {
return await page.evaluate(() => window.ketcher.getSequence());
}
Expand Down
2 changes: 1 addition & 1 deletion ketcher-autotests/tests/utils/macromolecules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function scrollDown(page: Page, scrollDelta: number) {

export async function chooseFileFormat(
page: Page,
fileFomat: 'Ket' | 'MDL Molfile V3000' | 'FASTA' | 'Sequence',
fileFomat: 'Ket' | 'MDL Molfile V3000' | 'FASTA' | 'Sequence' | 'IDT',
) {
await page.getByTestId('dropdown-select').click();
await waitForSpinnerFinishedWork(page, async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ const formatProperties: FormatPropertiesMap = {
['.fasta'],
true,
),
idt: new SupportedFormatProperties(
'IDT',
ChemicalMimeType.IDT,
['.idt'],
false,
),
sequence: new SupportedFormatProperties(
'SEQUENCE',
ChemicalMimeType.SEQUENCE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export enum SupportedFormat {
sdfV3000 = 'sdfV3000',
fasta = 'fasta',
sequence = 'sequence',
idt = 'idt',
unknown = 'unknown',
}

Expand Down
9 changes: 9 additions & 0 deletions packages/ketcher-core/src/application/ketcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ export class Ketcher {
return molfile;
}

getIdt(): Promise<string> {
return getStructure(
SupportedFormat.idt,
this.#formatterFactory,
this.#editor.struct(),
CoreEditor.provideEditorInstance()?.drawingEntitiesManager,
);
}

async getRxn(molfileFormat: MolfileFormat = 'v2000'): Promise<string> {
if (window.isPolymerEditorTurnedOn) {
throw new Error('RXN format is not available in macro mode');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export enum ChemicalMimeType {
RNA = 'chemical/x-rna-sequence',
DNA = 'chemical/x-dna-sequence',
PEPTIDE = 'chemical/x-peptide-sequence',
IDT = 'chemical/x-idt',
}

export interface WithStruct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const options: Array<Option> = [
{ id: 'mol', label: 'MDL Molfile V3000' },
{ id: 'seq', label: 'Sequence' },
{ id: 'fasta', label: 'FASTA' },
{ id: 'idt', label: 'IDT' },
];

const additionalOptions: Array<Option> = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ const options: Array<Option> = [
{ id: 'mol', label: 'MDL Molfile V3000' },
{ id: 'sequence', label: 'Sequence' },
{ id: 'fasta', label: 'FASTA' },
{ id: 'idt', label: 'IDT' },
];

const formatDetector = {
mol: ChemicalMimeType.Mol,
fasta: ChemicalMimeType.FASTA,
sequence: ChemicalMimeType.SEQUENCE,
idt: ChemicalMimeType.IDT,
};

const StyledModal = styled(Modal)({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
SupportedFormatProperties,
} from './supportedFormatProperties';

export type SupportedFormats = 'mol' | 'ket' | 'fasta' | 'sequence';
export type SupportedFormats = 'mol' | 'ket' | 'fasta' | 'sequence' | 'idt';

type FormatProperties = {
[key in SupportedFormats]: SupportedFormatProperties;
Expand Down Expand Up @@ -54,6 +54,13 @@ const formatProperties: FormatProperties = {
false,
{},
),
idt: new SupportedFormatProperties(
'IDT',
ChemicalMimeType.Idt,
['.idt'],
false,
{},
),
};

export const getPropertiesByFormat = (format: SupportedFormats) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum ChemicalMimeType {
Helm = 'chemical/x-helm',
Fasta = 'chemical/x-fasta',
Sequence = 'chemical/x-sequence',
Idt = 'chemical/x-idt',
}

interface SupportedFormatPropertiesOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export enum SupportedFormat {
SDF = 'sdf',
FASTA = 'fasta',
SEQUENCE = 'sequence',
IDT = 'idt',
}

export interface WithStruct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ function convertMimeTypeToOutputFormat(
format = SupportedFormat.SEQUENCE;
break;
}
case ChemicalMimeType.IDT: {
format = SupportedFormat.IDT;
break;
}
case ChemicalMimeType.UNKNOWN:
default: {
throw new Error('Unsupported chemical mime type');
Expand Down Expand Up @@ -271,6 +275,7 @@ class IndigoService implements StructService {
struct,
} = data;
const format = convertMimeTypeToOutputFormat(outputFormat);
console.log('convert format', format);

return new Promise((resolve, reject) => {
const action = ({ data }: OutputMessageWrapper) => {
Expand Down Expand Up @@ -308,6 +313,7 @@ class IndigoService implements StructService {
this.EE.removeListener(WorkerEvent.Convert, action);
this.EE.addListener(WorkerEvent.Convert, action);

console.log('convert worker.postMessage', inputMessage);
this.worker.postMessage(inputMessage);
});
}
Expand Down

0 comments on commit e2fd5c9

Please sign in to comment.