How to wait for a full sync? (How to test PowerSync-based app?)
I'm trying to make some integraiton tests with Vitest. Some typical scenarios:
- Call backend API affecting some tables in Sync Rules -> expect changes downloaded to the client
- Write some data to client tables -> expect changes uploaded to the backend (-> expect changes downloaded to the client?)
Consider a test with Vitest and PowerSync Node SDK:
test('User signs up', async ({apiClient, kylesyDb, powersyncDb}) => {
await apiClient.signUp({email: '...'});
// HOW TO WAIT FOR A SYNC?
// I could only come up with something like
// await powersyncDb.disconnectAndClear();
// await powersyncDb.connect(connector);
// But it's not an honest test
expect(await db.selectFrom('user').selectAll().executeTakeFirst()).toBeDefined()
});
So, how one awaits for client Sqlite to be in full sync with backend DB?
In the nodejs client, I use waitForFirstSync().
Maybe it will work for your tests
const powerSync = new PowerSyncDatabase({ ... });
await powerSync.connect(...);
await powerSync.waitForReady();
await powerSync.waitForFirstSync();
@douglascayers I'm afraid it doesn't work past the actual first sync:
const statusMatches =
priority === undefined
? (status: SyncStatus) => status.hasSynced
: (status: SyncStatus) => status.statusForPriority(priority).hasSynced;
if (statusMatches(this.currentStatus)) {
return;
}
I also tried checking for powerSync.currentStatus, but the status doesn't change syncronously.
Basically, @powersync-ja how to test software made with PowerSync?
We typically suggest using Vitest's waitFor utility (if possible). After initiating the upload, you can use waitFor to create a test that queries the client database and verifies the expected synced value. The utility will automatically retry the assertion if it initially fails, allowing time for the sync to complete.
We have an example of this here.
Alternatively, you could monitor the sync status directly. This method involves first capturing the current lastSyncedAt timestamp from the sync status, then making your desired change, and finally waiting for the lastSyncedAt value to advance beyond the initial timestamp. This ensures that the synchronization process has completed before proceeding with your assertions.
@dean-journeyapps I tried the waitFor method (the data just never appears in the Sqlite) but it doesn't work despite reconnecting does . Like somehow sync is not working under Vitest, I dunno.
@dean-journeyapps I tried the
waitFormethod (the data just never appears in the Sqlite) but it doesn't work despite reconnecting does . Like somehow sync is not working under Vitest, I dunno.
This seems like a more general sync issue. Possibly related to your backend connector. We would need to see more of your code to properly help diagnose that issue.
Is your client database connected when testing?
@dean-journeyapps I see, I'll try to debug more and make a minimal repro.