Packages
Local development
Copy page
Build your app in a desktop browser with mockLia(), a pretend Lia that answers every call with a test player. Change its answers, send events, and debug every message.
Outside the Lia app there's no frame bridge, so every call fails with not_in_lia. mockLia() puts a pretend Lia in its place: it answers every call the way Lia would, with a test player in test mode, so your whole app runs in a desktop browser or in tests.
#Turn it on
Call it before your first SDK call, and only outside Lia:
import { init, isLia, mockLia } from '@lia-labs/sdk';
if (!isLia()) mockLia();
const me = await init(); // { player: { name: 'tester' }, mode: 'test', ... }With a framework package it's the same import, from that package. Keep it out of production builds with your bundler's dev flag if you like (if (import.meta.env.DEV && !isLia())).
#What it answers
| Call | The mock answers |
|---|---|
init | A test player (tester), test mode, English, light, a sheet, notifications available |
pay | A paid charge, ch_mock0001 and up |
showAd and its shortcuts | A watched video (ad_mock), or a shown interstitial |
confirm, showPopup | Yes, and the first button |
requestNotifications, inviteFriend | Allowed, invited |
submitScore, leaderboard | Keeps your best score and ranks you first |
| Storage | Kept in memory for the page's life |
biometric | Available Face ID, authenticated |
| Everything else | What Lia answers when it works |
#Change its answers
Pass init to change who and how, and onMethod to decide any answer yourself. Return a value to answer, throw { code } to fail, or call next() for the mock's own answer:
mockLia({
init: { language: 'ar', rtl: true, theme: 'dark', startParam: 'room-k3x9' },
latency: 300, // ms before each answer, to see your loading states
onMethod: (call, next) => {
if (call.method === 'pay' && call.params.productId === 'gold-pack') throw { code: 'cancelled' };
if (call.method === 'showAd') return { watched: false, shown: false, reason: 'no_ad' };
return next();
},
});#Send events
The mock can send any of Lia's events, to try how your app reacts:
const mock = mockLia();
mock.event('theme', { colorScheme: 'dark', theme: { bg_color: '#09090B', text_color: '#F5F5F7' } });
mock.event('soundChanged', { on: false });
mock.event('startParam', { startParam: 'room-a81c' });
mock.event('mainButtonClicked');
mock.event('pause');mock.calls lists every call your page made, and mock.restore() removes the mock.
#In tests
The same mock makes tests simple (here with Vitest and jsdom):
import { afterEach, expect, it } from 'vitest';
import { init, mainButton, mockLia, resetForTests, resetStateForTests } from '@lia-labs/sdk';
afterEach(() => {
resetForTests();
resetStateForTests();
});
it('shows Buy once the player is in', async () => {
const mock = mockLia();
await init();
mainButton.setParams({ text: 'Buy', isVisible: true });
await Promise.resolve();
expect(mock.calls.at(-1)).toMatchObject({ method: 'bottomButton', params: { text: 'Buy', visible: true } });
mock.restore();
});#See every message
setDebug(true) logs every call, answer and event to the console, inside Lia too:
import { setDebug } from '@lia-labs/sdk';
setDebug(true);
// [lia] call pay { productId: 'extra-lives' }
// [lia] event pause undefined
// [lia] answer pay { id: 7, ok: true, result: { chargeId: 'ch_…', productId: 'extra-lives' } }Pass a second argument to send them to your own logger, which helps inside Lia where there's no web inspector: setDebug(true, { log: send, warn: send, error: send }).
#Your server
The mock's session (lias_mock) isn't one Lia signed, so /session/verify says it isn't valid. Give your server a development path, or try server flows inside Lia as a tester. See Testing your app.