Skip to content

Commit

Permalink
Chore: Desktop: Fix test failures due to race condition (#11417)
Browse files Browse the repository at this point in the history
Co-authored-by: Laurent Cozic <[email protected]>
  • Loading branch information
personalizedrefrigerator and laurent22 authored Nov 20, 2024
1 parent 48f5da6 commit 13d8fbb
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 40 deletions.
3 changes: 3 additions & 0 deletions packages/app-desktop/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@ class Application extends BaseApplication {
SearchEngine.instance().scheduleSyncTables();
});

// Used by tests
ipcRenderer.send('startup-finished');

// setTimeout(() => {
// void populateDatabase(reg.db(), {
// clearDatabase: true,
Expand Down
9 changes: 5 additions & 4 deletions packages/app-desktop/integration-tests/goToAnything.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Locator } from '@playwright/test';

test.describe('goToAnything', () => {
test('clicking outside of go to anything should close it', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Test');
await mainScreen.noteEditor.waitFor();
const goToAnything = mainScreen.goToAnything;
await goToAnything.open(electronApp);
Expand All @@ -19,7 +20,7 @@ test.describe('goToAnything', () => {
});

test('pressing escape in go to anything should close it ', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const goToAnything = mainScreen.goToAnything;

// Pressing Escape to close the dialog should work even if opened multiple times in a row.
Expand All @@ -33,7 +34,7 @@ test.describe('goToAnything', () => {
});

test('closing go to anything should restore the original keyboard focus', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('');

const initialFocusLocators: [Locator, boolean][] = [
Expand Down Expand Up @@ -65,7 +66,7 @@ test.describe('goToAnything', () => {
});

test('should be possible to show the set tags dialog from goToAnything', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Test note');

const goToAnything = mainScreen.goToAnything;
Expand Down
10 changes: 5 additions & 5 deletions packages/app-desktop/integration-tests/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ test.describe('main', () => {
// A window should open with the correct title
expect(await mainWindow.title()).toMatch(/^Joplin/);

const mainPage = new MainScreen(mainWindow);
const mainPage = await new MainScreen(mainWindow).setup();
await mainPage.waitFor();
});

test('should be able to create and edit a new note', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const editor = await mainScreen.createNewNote('Test note');

// Note list should contain the new note
Expand All @@ -41,7 +41,7 @@ test.describe('main', () => {
});

test('mermaid and KaTeX should render', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const editor = await mainScreen.createNewNote('🚧 Test 🚧');

const testCommitId = 'bf59b2';
Expand Down Expand Up @@ -97,7 +97,7 @@ test.describe('main', () => {
});

test('should correctly resize large images', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Image resize test (part 1)');
const editor = mainScreen.noteEditor;

Expand Down Expand Up @@ -138,7 +138,7 @@ test.describe('main', () => {

for (const target of ['', '_blank']) {
test(`clicking on an external link with target=${JSON.stringify(target)} should try to launch a browser`, async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

// Mock openExternal
Expand Down
12 changes: 6 additions & 6 deletions packages/app-desktop/integration-tests/markdownEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import activateMainMenuItem from './util/activateMainMenuItem';

test.describe('markdownEditor', () => {
test('preview pane should render images in HTML notes', async ({ mainWindow, electronApp }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

await mainScreen.importHtmlDirectory(electronApp, join(__dirname, 'resources', 'html-import'));
Expand Down Expand Up @@ -36,7 +36,7 @@ test.describe('markdownEditor', () => {
});

test('preview pane should render PDFs', async ({ mainWindow, electronApp }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('PDF attachments');
const editor = mainScreen.noteEditor;

Expand Down Expand Up @@ -81,7 +81,7 @@ test.describe('markdownEditor', () => {
});

test('preview pane should render video attachments', async ({ mainWindow, electronApp }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Media attachments');
const editor = mainScreen.noteEditor;

Expand All @@ -105,7 +105,7 @@ test.describe('markdownEditor', () => {
});

test('arrow keys should navigate the toolbar', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

await mainScreen.createNewNote('Note 1');
Expand Down Expand Up @@ -142,7 +142,7 @@ test.describe('markdownEditor', () => {
});

test('should sync local search between the viewer and editor', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();
const noteEditor = mainScreen.noteEditor;

Expand Down Expand Up @@ -198,7 +198,7 @@ test.describe('markdownEditor', () => {
});

test('should move focus when the visible editor panes change', async ({ mainWindow, electronApp }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();
const noteEditor = mainScreen.noteEditor;

Expand Down
6 changes: 6 additions & 0 deletions packages/app-desktop/integration-tests/models/MainScreen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export default class MainScreen {
this.goToAnything = new GoToAnything(page, this);
}

public async setup() {
await this.waitFor();
await this.sidebar.createNewFolder('Test');
return this;
}

public async waitFor() {
await this.newNoteButton.waitFor();
await this.noteList.waitFor();
Expand Down
7 changes: 4 additions & 3 deletions packages/app-desktop/integration-tests/noteList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import setMessageBoxResponse from './util/setMessageBoxResponse';

test.describe('noteList', () => {
test('should be possible to edit notes in a different notebook when searching', async ({ mainWindow, electronApp }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

const folderAHeader = await sidebar.createNewFolder('Folder A');
Expand Down Expand Up @@ -39,7 +39,7 @@ test.describe('noteList', () => {
});

test('shift-delete should ask to permanently delete notes, but only when the note list is focused', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

const folderBHeader = await sidebar.createNewFolder('Folder B');
Expand Down Expand Up @@ -76,7 +76,7 @@ test.describe('noteList', () => {
});

test('arrow keys should navigate the note list', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

await sidebar.createNewFolder('Folder');
Expand All @@ -89,6 +89,7 @@ test.describe('noteList', () => {
const noteList = mainScreen.noteList;
await noteList.sortByTitle(electronApp);
await noteList.focusContent(electronApp);

// The most recently-created note should be visible
const note4Item = noteList.getNoteItemByTitle('note_4');
const note3Item = noteList.getNoteItemByTitle('note_3');
Expand Down
2 changes: 1 addition & 1 deletion packages/app-desktop/integration-tests/pluginApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MainScreen from './models/MainScreen';
test.describe('pluginApi', () => {
test('the editor.setText command should update the current note (use RTE: false)', async ({ startAppWithPlugins }) => {
const { app, mainWindow } = await startAppWithPlugins(['resources/test-plugins/execCommand.js']);
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('First note');
const editor = mainScreen.noteEditor;

Expand Down
8 changes: 4 additions & 4 deletions packages/app-desktop/integration-tests/richTextEditor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { basename, join } from 'path';

test.describe('richTextEditor', () => {
test('HTML links should be preserved when editing a note', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Testing!');
const editor = mainScreen.noteEditor;

Expand Down Expand Up @@ -50,7 +50,7 @@ test.describe('richTextEditor', () => {
});

test('should watch resources for changes when opened with ctrl+click', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Testing!');
const editor = mainScreen.noteEditor;

Expand Down Expand Up @@ -83,7 +83,7 @@ test.describe('richTextEditor', () => {
});

test('pressing Tab should indent', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Testing tabs!');
const editor = mainScreen.noteEditor;

Expand Down Expand Up @@ -121,7 +121,7 @@ test.describe('richTextEditor', () => {
});

test('should be possible to navigate between the note title and rich text editor with enter/down/up keys', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.createNewNote('Testing keyboard navigation!');

const editor = mainScreen.noteEditor;
Expand Down
6 changes: 3 additions & 3 deletions packages/app-desktop/integration-tests/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SettingsScreen from './models/SettingsScreen';

test.describe('settings', () => {
test('should be possible to remove sort order buttons in settings', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

// Sort order buttons should be visible by default
Expand Down Expand Up @@ -35,7 +35,7 @@ test.describe('settings', () => {
});

test('clicking the sync wizard button in settings should open a dialog', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();
await mainScreen.openSettings(electronApp);

Expand All @@ -52,7 +52,7 @@ test.describe('settings', () => {
});

test('should be possible to navigate settings screen tabs with the arrow keys', async ({ electronApp, mainWindow, startupPluginsLoaded }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await startupPluginsLoaded;

await mainScreen.waitFor();
Expand Down
8 changes: 4 additions & 4 deletions packages/app-desktop/integration-tests/sidebar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import MainScreen from './models/MainScreen';

test.describe('sidebar', () => {
test('should be able to create new folders', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

for (let i = 0; i < 3; i++) {
Expand All @@ -17,7 +17,7 @@ test.describe('sidebar', () => {
});

test('should allow changing the focused folder with the arrow keys', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

const folderAHeader = await sidebar.createNewFolder('Folder A');
Expand Down Expand Up @@ -45,7 +45,7 @@ test.describe('sidebar', () => {
});

test('should allow changing the parent of a folder by drag-and-drop', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

const parentFolderHeader = await sidebar.createNewFolder('Parent folder');
Expand Down Expand Up @@ -77,7 +77,7 @@ test.describe('sidebar', () => {
});

test('all notes section should list all notes', async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
const sidebar = mainScreen.sidebar;

const testFolderA = await sidebar.createNewFolder('Folder A');
Expand Down
4 changes: 2 additions & 2 deletions packages/app-desktop/integration-tests/simpleBackup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test.describe('simpleBackup', () => {
test('should have a section in settings', async ({ electronApp, startupPluginsLoaded, mainWindow }) => {
await startupPluginsLoaded;

const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

// Open settings (check both labels so that this works on MacOS)
Expand All @@ -24,7 +24,7 @@ test.describe('simpleBackup', () => {
test('should be possible to create a backup', async ({ electronApp, startupPluginsLoaded, mainWindow }) => {
await startupPluginsLoaded;

const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

// Backups should work
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const createStartupArgs = (profileDirectory: string) => {
// We need to run with --env dev to disable the single instance check.
return [
'main.js', '--env', 'dev', '--profile', profileDirectory,
'main.js', '--env', 'dev', '--no-welcome', '--profile', profileDirectory,
];
};

Expand Down
20 changes: 16 additions & 4 deletions packages/app-desktop/integration-tests/util/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,20 @@ const getAndResizeMainWindow = async (electronApp: ElectronApplication) => {
return mainWindow;
};

const waitForStartupPlugins = async (electronApp: ElectronApplication) => {
return electronApp.evaluate(({ ipcMain }) => {
const waitForMainMessage = (electronApp: ElectronApplication, messageId: string) => {
return electronApp.evaluate(({ ipcMain }, messageId) => {
return new Promise<void>(resolve => {
ipcMain.once('startup-plugins-loaded', () => resolve());
ipcMain.once(messageId, () => resolve());
});
});
}, messageId);
};

const waitForAppLoaded = async (electronApp: ElectronApplication) => {
await waitForMainMessage(electronApp, 'startup-finished');
};

const waitForStartupPlugins = async (electronApp: ElectronApplication) => {
await waitForMainMessage(electronApp, 'startup-plugins-loaded');
};

const testDir = dirname(__dirname);
Expand All @@ -62,7 +70,9 @@ export const test = base.extend<JoplinFixtures>({
electronApp: async ({ profileDirectory }, use) => {
const startupArgs = createStartupArgs(profileDirectory);
const electronApp = await electron.launch({ args: startupArgs });
const startupPromise = waitForAppLoaded(electronApp);
await setDarkMode(electronApp, false);
await startupPromise;

await use(electronApp);

Expand All @@ -85,8 +95,10 @@ export const test = base.extend<JoplinFixtures>({
pluginPaths.map(path => resolve(testDir, path)).join(','),
],
});
const startupPromise = waitForAppLoaded(electronApp);
const mainWindowPromise = getAndResizeMainWindow(electronApp);
await waitForStartupPlugins(electronApp);
await startupPromise;

return {
app: electronApp,
Expand Down
4 changes: 2 additions & 2 deletions packages/app-desktop/integration-tests/wcag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const expectNoViolations = async (page: Page) => {
test.describe('wcag', () => {
for (const tabName of ['General', 'Plugins']) {
test(`should not detect significant issues in the settings screen ${tabName} tab`, async ({ electronApp, mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

await mainScreen.openSettings(electronApp);
Expand All @@ -50,7 +50,7 @@ test.describe('wcag', () => {
}

test('should not detect significant issues in the main screen with an open note', async ({ mainWindow }) => {
const mainScreen = new MainScreen(mainWindow);
const mainScreen = await new MainScreen(mainWindow).setup();
await mainScreen.waitFor();

await mainScreen.createNewNote('Test');
Expand Down
3 changes: 2 additions & 1 deletion packages/tools/cspell/dictionary4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,6 @@ Rocketbook
datamatrix
nosniff
CNIL
setsize
Comprar
seguidores
seguidores

0 comments on commit 13d8fbb

Please sign in to comment.