/*
* Copyright (C) 2023-2024 Yomitan Authors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import {test as base, chromium} from '@playwright/test';
import path from 'path';
import {fileURLToPath} from 'url';
const dirname = path.dirname(fileURLToPath(import.meta.url));
export const root = path.join(dirname, '..', '..');
export const test = base.extend({
// eslint-disable-next-line no-empty-pattern
context: async ({}, use) => {
const pathToExtension = path.join(root, 'ext');
const context = await chromium.launchPersistentContext('', {
// Disabled: headless: false,
args: [
'--headless=new',
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`
]
});
await use(context);
await context.close();
},
extensionId: async ({context}, use) => {
let [background] = context.serviceWorkers();
if (!background) {
background = await context.waitForEvent('serviceworker');
}
const extensionId = background.url().split('/')[2];
await use(extensionId);
}
});
export const expect = test.expect;
export const mockModelFieldNames = [
'Word',
'Reading',
'Audio',
'Sentence'
];
/** @type {{[key: string]: string|undefined}} */
export const mockModelFieldsToAnkiValues = {
Word: '{expression}',
Reading: '{furigana-plain}',
Sentence: '{clipboard-text}',
Audio: '{audio}'
};
/**
* @param {import('playwright').Route} route
* @returns {Promise}
*/
export async function mockAnkiRouteHandler(route) {
const reqBody = route.request().postDataJSON();
const respBody = ankiRouteResponses[reqBody.action];
if (!respBody) {
return route.abort();
}
await route.fulfill(respBody);
}
/**
* @param {import('playwright').Page} page
* @param {string} text
* @returns {Promise}
*/
export const writeToClipboardFromPage = async (page, text) => {
await page.evaluate(`navigator.clipboard.writeText('${text}')`);
};
export const expectedAddNoteBody = {
version: 2,
action: 'addNote',
params: {
note: {
fields: {
Word: '読む',
Reading: '読[よ]む',
Audio: '[sound:mock_audio.mp3]',
Sentence: '読むの例文'
},
tags: ['yomitan'],
deckName: 'Mock Deck',
modelName: 'Mock Model',
options: {
allowDuplicate: false,
duplicateScope: 'collection',
duplicateScopeOptions: {
deckName: null,
checkChildren: false,
checkAllModels: false
}
}
}
}
};
const baseAnkiResp = {
status: 200,
contentType: 'text/json'
};
/** @type {{[key: string]: import('core').SerializableObject}} */
const ankiRouteResponses = {
version: Object.assign({body: JSON.stringify(6)}, baseAnkiResp),
deckNames: Object.assign({body: JSON.stringify(['Mock Deck'])}, baseAnkiResp),
modelNames: Object.assign({body: JSON.stringify(['Mock Model'])}, baseAnkiResp),
modelFieldNames: Object.assign({body: JSON.stringify(mockModelFieldNames)}, baseAnkiResp),
canAddNotes: Object.assign({body: JSON.stringify([true, true])}, baseAnkiResp),
storeMediaFile: Object.assign({body: JSON.stringify('mock_audio.mp3')}, baseAnkiResp),
addNote: Object.assign({body: JSON.stringify(102312488912)}, baseAnkiResp)
};