Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions e2e/smoke.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'path';
import { existsSync } from 'fs';
import { test, expect, Page } from '@playwright/test';
import { launchApp, Harness } from './support';
import { toAssetUrl } from '../src/main/util';
Expand Down Expand Up @@ -29,6 +30,55 @@ test.describe('first run', () => {
});

test.describe('seeded library', () => {
test('previews and imports a prepared local auto-chart', async () => {
harness = await launchApp({ seedLibrary: true });
await harness.app.evaluate(({ dialog }, importDir) => {
dialog.showOpenDialog = async () => ({
canceled: false,
filePaths: [importDir],
});
}, harness.importDir);
page = await harness.app.firstWindow();

await page.getByRole('button', { name: 'Import song' }).click();
await expect(page.getByText('Review song import')).toBeVisible();
await expect(page.getByText('Auto-charted with STRUM')).toBeVisible();
await expect(
page.getByText('Existing album artwork will be preserved.'),
).toBeVisible();

if (process.env.SIGHTKICK_IMPORT_PREVIEW_PROOF) {
await page.screenshot({
path: process.env.SIGHTKICK_IMPORT_PREVIEW_PROOF,
});
}

await page.getByRole('button', { name: 'Add to library' }).click();

const row = page.getByTestId(/song-item-/).filter({ hasText: 'Raging' });

await expect(row).toBeVisible();
await expect(row.getByText('Auto-charted with STRUM')).toBeVisible();
await expect(row.getByText('play once to earn stars')).toBeVisible();

await page.getByTestId('song-search').fill('STRUM');
await expect(row).toBeVisible();

const importedDir = path.join(
harness.libraryDir,
'Kygo feat. Kodaline - Raging',
);

expect(existsSync(path.join(importedDir, 'album.png'))).toBe(true);
expect(existsSync(path.join(importedDir, '.sightkick'))).toBe(true);

if (process.env.SIGHTKICK_IMPORT_AFTER_PROOF) {
await page.screenshot({
path: process.env.SIGHTKICK_IMPORT_AFTER_PROOF,
});
}
});

test('scans the folder, lists the song, and renders real sheet music', async () => {
harness = await launchApp({ seedLibrary: true });
page = await harness.app.firstWindow();
Expand Down
76 changes: 52 additions & 24 deletions e2e/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,38 @@ const MAIN_ENTRY = path.join(__dirname, '..', 'out', 'main', 'index.js');

export interface Harness {
app: ElectronApplication;
importDir: string;
libraryDir: string;
}

const ALBUM_PNG = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
'base64',
);
const EXPERT_DRUM_CHART = [
'[Song]',
'{',
' Resolution = 480',
'}',
'[SyncTrack]',
'{',
' 0 = TS 4',
' 0 = B 120000',
'}',
'[ExpertDrums]',
'{',
' 0 = N 0 0',
' 480 = N 1 0',
' 960 = N 0 0',
' 1440 = N 1 0',
' 1920 = N 0 0',
' 2400 = N 2 0',
' 2400 = N 66 0',
' 2880 = N 0 0',
' 3360 = N 1 0',
'}',
'',
].join('\n');

function writeFixtureLibrary(): string {
const libraryDir = mkdtempSync(path.join(tmpdir(), 'sightkick-library-'));
Expand All @@ -37,35 +62,37 @@ function writeFixtureLibrary(): string {
].join('\n'),
);

writeFileSync(path.join(songDir, 'notes.chart'), EXPERT_DRUM_CHART);

return libraryDir;
}

function writeImportFixture(): string {
const root = mkdtempSync(path.join(tmpdir(), 'sightkick-import-'));
const songDir = path.join(root, 'prepared-song');

mkdirSync(songDir);
writeFileSync(path.join(songDir, 'album.png'), ALBUM_PNG);
writeFileSync(path.join(songDir, 'notes.chart'), EXPERT_DRUM_CHART);
writeFileSync(path.join(songDir, 'song.mp3'), 'test audio');
writeFileSync(
path.join(songDir, 'notes.chart'),
path.join(songDir, 'song.ini'),
[
'[Song]',
'{',
' Resolution = 480',
'}',
'[SyncTrack]',
'{',
' 0 = TS 4',
' 0 = B 120000',
'}',
'[ExpertDrums]',
'{',
' 0 = N 0 0',
' 480 = N 1 0',
' 960 = N 0 0',
' 1440 = N 1 0',
' 1920 = N 0 0',
' 2400 = N 2 0',
' 2400 = N 66 0',
' 2880 = N 0 0',
' 3360 = N 1 0',
'}',
'[song]',
'name = Raging',
'artist = Kygo feat. Kodaline',
'album = Cloud Nine',
'auto_chart = True',
'auto_chart_tool = STRUM (OCTAVE AI auto-charter)',
'charter = STRUM',
'pro_drums = True',
'five_lane_drums = False',
'diff_drums = 2',
'',
].join('\n'),
);

return libraryDir;
return songDir;
}

function seedUserData(seed: Record<string, unknown>): string {
Expand All @@ -83,6 +110,7 @@ export async function launchApp(
options: { seedLibrary?: boolean } = {},
): Promise<Harness> {
const libraryDir = writeFixtureLibrary();
const importDir = writeImportFixture();
const userDataDir = seedUserData(
options.seedLibrary ? { lastOpenedPath: libraryDir } : {},
);
Expand All @@ -95,5 +123,5 @@ export async function launchApp(
},
});

return { app, libraryDir };
return { app, importDir, libraryDir };
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"es-toolkit": "^1.47.1",
"fuse.js": "^7.0.0",
"ini": "^4.1.1",
"music-metadata": "^11.14.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.18.1",
Expand Down
3 changes: 3 additions & 0 deletions src/main/AppState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { listenMidi, loadMidiDeviceList, stopListenMidi } from './ipc/midi';
import { updateSong } from './ipc/updateSong';
import { rescanSongs } from './ipc/rescanSongs';
import { exportPdf } from './ipc/exportPdf';
import { importSong, selectImportSong } from './ipc/importSong';

class AppState {
private static instance: AppState;
Expand Down Expand Up @@ -100,6 +101,8 @@ class AppState {
ipcMain.on('load-song-list', loadSongList);
ipcMain.on('rescan-songs', rescanSongs);
ipcMain.on('download-song', downloadSong);
ipcMain.on('select-import-song', selectImportSong);
ipcMain.on('import-song', importSong);

ipcMain.on('check-stem-tools', checkStemTools);
ipcMain.on('check-stem-tools-update', checkStemToolsUpdate);
Expand Down
Loading