mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-01-16 22:31:25 -08:00
134 lines
4.5 KiB
TypeScript
134 lines
4.5 KiB
TypeScript
import { After, Before, setWorldConstructor, Then, When } from '@cucumber/cucumber';
|
|
import { _electron as electron } from 'playwright';
|
|
import type { ElectronApplication, Page } from 'playwright';
|
|
import { getPackedAppPath } from '../supports/paths';
|
|
|
|
class ApplicationWorld {
|
|
app: ElectronApplication | undefined;
|
|
mainWindow: Page | undefined;
|
|
}
|
|
|
|
setWorldConstructor(ApplicationWorld);
|
|
|
|
Before(async function(this: ApplicationWorld) {
|
|
console.log('Starting test scenario');
|
|
});
|
|
|
|
After(async function(this: ApplicationWorld) {
|
|
if (this.app) {
|
|
try {
|
|
await this.app.close();
|
|
console.log('Application closed successfully');
|
|
} catch (error) {
|
|
console.error('Error during cleanup:', error);
|
|
}
|
|
this.app = undefined;
|
|
this.mainWindow = undefined;
|
|
}
|
|
});
|
|
|
|
When('I launch the TidGi application', async function(this: ApplicationWorld) {
|
|
// For E2E tests on dev mode, use the packaged test version with NODE_ENV environment variable baked in
|
|
|
|
const packedAppPath = getPackedAppPath();
|
|
console.log('Launching packaged test app at:', packedAppPath);
|
|
|
|
try {
|
|
this.app = await electron.launch({
|
|
executablePath: packedAppPath,
|
|
// Add debugging options to prevent app from closing
|
|
args: ['--no-sandbox', '--disable-dev-shm-usage'],
|
|
env: {
|
|
...process.env,
|
|
NODE_ENV: 'test',
|
|
},
|
|
});
|
|
this.mainWindow = await this.app.firstWindow();
|
|
} catch (error) {
|
|
throw new Error(`Failed to launch TidGi application: ${error as Error}. You should run \`pnpm run package:dev\` before running the tests to ensure the app is built.`);
|
|
}
|
|
});
|
|
|
|
When('I wait for {int} seconds', async function(seconds: number) {
|
|
await new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
|
});
|
|
|
|
When('I wait for the page to load completely', async function(this: ApplicationWorld) {
|
|
await this.mainWindow?.waitForLoadState('networkidle', { timeout: 30000 });
|
|
});
|
|
|
|
Then('I should see an element with selector {string}', async function(this: ApplicationWorld, selector: string) {
|
|
try {
|
|
await this.mainWindow?.waitForSelector(selector, { timeout: 10000 });
|
|
const isVisible = await this.mainWindow?.isVisible(selector);
|
|
if (!isVisible) {
|
|
throw new Error(`Element with selector "${selector}" is not visible`);
|
|
}
|
|
} catch (error) {
|
|
throw new Error(`Failed to find visible element with selector "${selector}": ${error as Error}`);
|
|
}
|
|
});
|
|
|
|
Then('I should {word} see text {string}', async function(this: ApplicationWorld, modifier: string, text: string) {
|
|
switch (modifier) {
|
|
case 'always':
|
|
case '': {
|
|
// For "I should see text" - wait for text to appear
|
|
try {
|
|
await this.mainWindow?.waitForFunction(
|
|
(searchText) => document.body.textContent?.includes(searchText),
|
|
text,
|
|
{ timeout: 10000 },
|
|
);
|
|
} catch (error) {
|
|
throw new Error(`Failed to find text "${text}" on the page: ${error as Error}`);
|
|
}
|
|
break;
|
|
}
|
|
case 'not': {
|
|
// For "I should not see text" - check text is not present
|
|
const bodyContent = await this.mainWindow?.textContent('body');
|
|
if (bodyContent?.includes(text)) {
|
|
throw new Error(`Text "${text}" should not be visible but was found on the page`);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
throw new Error(`Unsupported text modifier: "${modifier}". Use "not" or leave empty`);
|
|
}
|
|
});
|
|
|
|
Then('I should see text {string}', async function(this: ApplicationWorld, text: string) {
|
|
try {
|
|
// Wait for the text to appear on the page
|
|
await this.mainWindow?.waitForFunction(
|
|
(searchText) => document.body.textContent?.includes(searchText),
|
|
text,
|
|
{ timeout: 10000 },
|
|
);
|
|
} catch (error) {
|
|
throw new Error(`Failed to find text "${text}" on the page: ${error as Error}`);
|
|
}
|
|
});
|
|
|
|
Then('the window title should {word} {string}', async function(this: ApplicationWorld, action: string, value: string) {
|
|
const actualTitle = await this.mainWindow?.title();
|
|
|
|
switch (action) {
|
|
case 'contain':
|
|
if (!actualTitle?.includes(value)) {
|
|
throw new Error(`Expected window title to contain "${value}" but got "${actualTitle}"`);
|
|
}
|
|
console.log(`✓ Window title contains "${value}"`);
|
|
break;
|
|
case 'equal':
|
|
case 'be':
|
|
if (actualTitle !== value) {
|
|
throw new Error(`Expected window title to be "${value}" but got "${actualTitle}"`);
|
|
}
|
|
console.log(`✓ Window title is "${value}"`);
|
|
break;
|
|
default:
|
|
throw new Error(`Unsupported title action: "${action}". Use "contain", "equal", or "be"`);
|
|
}
|
|
});
|