diff --git a/test/package/browser/template/README.md b/test/package/browser/template/README.md index 8bf44061b..38f2e248d 100644 --- a/test/package/browser/template/README.md +++ b/test/package/browser/template/README.md @@ -8,6 +8,7 @@ This directory is intended to be used for testing the following aspects of the a It contains three files, each of which import ably-js in different manners, and provide a way to briefly exercise its functionality: - `src/index-default.ts` imports the default ably-js package (`import { Realtime } from 'ably'`). +- `src/index-liveobjects.ts` imports the LiveObjects ably-js plugin (`import LiveObjects from 'ably/liveobjects'`). - `src/index-modular.ts` imports the tree-shakable ably-js package (`import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modular'`). - `src/ReactApp.tsx` imports React hooks from the ably-js package (`import { useChannel } from 'ably/react'`). @@ -25,6 +26,7 @@ This directory exposes three package scripts that are to be used for testing: - `build`: Uses esbuild to create: 1. a bundle containing `src/index-default.ts` and ably-js; - 2. a bundle containing `src/index-modular.ts` and ably-js. + 2. a bundle containing `src/index-liveobjects.ts` and ably-js. + 3. a bundle containing `src/index-modular.ts` and ably-js. - `test`: Using the bundles created by `build` and playwright components setup, tests that the code that exercises ably-js’s functionality is working correctly in a browser. - `typecheck`: Type-checks the code that imports ably-js. diff --git a/test/package/browser/template/package.json b/test/package/browser/template/package.json index a05aa0497..f2c023b6e 100644 --- a/test/package/browser/template/package.json +++ b/test/package/browser/template/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "scripts": { - "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist", + "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-liveobjects.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist", "typecheck": "tsc --project src -noEmit", "test-support:server": "ts-node server/server.ts", "test": "npm run test:lib && npm run test:hooks", diff --git a/test/package/browser/template/server/resources/index-liveobjects.html b/test/package/browser/template/server/resources/index-liveobjects.html new file mode 100644 index 000000000..b7f284af5 --- /dev/null +++ b/test/package/browser/template/server/resources/index-liveobjects.html @@ -0,0 +1,11 @@ + + + + + Ably NPM package test (LiveObjects plugin export) + + + + + + diff --git a/test/package/browser/template/server/server.ts b/test/package/browser/template/server/server.ts index 2409fc30c..faa1399f7 100644 --- a/test/package/browser/template/server/server.ts +++ b/test/package/browser/template/server/server.ts @@ -5,7 +5,7 @@ async function startWebServer(listenPort: number) { const server = express(); server.get('/', (req, res) => res.send('OK')); server.use(express.static(path.join(__dirname, '/resources'))); - for (const filename of ['index-default.js', 'index-modular.js']) { + for (const filename of ['index-default.js', 'index-liveobjects.js', 'index-modular.js']) { server.use(`/${filename}`, express.static(path.join(__dirname, '..', 'dist', filename))); } diff --git a/test/package/browser/template/src/index-liveobjects.ts b/test/package/browser/template/src/index-liveobjects.ts new file mode 100644 index 000000000..9334aadf4 --- /dev/null +++ b/test/package/browser/template/src/index-liveobjects.ts @@ -0,0 +1,43 @@ +import * as Ably from 'ably'; +import LiveObjects from 'ably/liveobjects'; +import { createSandboxAblyAPIKey } from './sandbox'; + +globalThis.testAblyPackage = async function () { + const key = await createSandboxAblyAPIKey({ featureFlags: ['enableChannelState'] }); + + const realtime = new Ably.Realtime({ key, environment: 'sandbox', plugins: { LiveObjects } }); + + const channel = realtime.channels.get('channel', { modes: ['STATE_SUBSCRIBE', 'STATE_PUBLISH'] }); + // check liveObjects can be accessed + const liveObjects = channel.liveObjects; + await channel.attach(); + // root should be a LiveMap object + const root: Ably.LiveMap = await liveObjects.getRoot(); + + // check root is recognized as LiveMap TypeScript type + root.get('someKey'); + root.size(); + + // check LiveMap subscription callback has correct TypeScript types + const { unsubscribe } = root.subscribe(({ update }) => { + switch (update.someKey) { + case 'removed': + case 'updated': + break; + default: + // check all possible types are exhausted + const shouldExhaustAllTypes: never = update.someKey; + } + }); + unsubscribe(); + + // check LiveCounter types also behave as expected + const counter = root.get('randomKey') as Ably.LiveCounter | undefined; + // use nullish coalescing as we didn't actually create a counter object on the root, + // so the next calls would fail. we only need to check that TypeScript types work + const value: number = counter?.value(); + const counterSubscribeResponse = counter?.subscribe(({ update }) => { + const shouldBeANumber: number = update.inc; + }); + counterSubscribeResponse?.unsubscribe(); +}; diff --git a/test/package/browser/template/src/sandbox.ts b/test/package/browser/template/src/sandbox.ts index 100ab22f0..54c5f2e64 100644 --- a/test/package/browser/template/src/sandbox.ts +++ b/test/package/browser/template/src/sandbox.ts @@ -1,10 +1,14 @@ import testAppSetup from '../../../../common/ably-common/test-resources/test-app-setup.json'; -export async function createSandboxAblyAPIKey() { +export async function createSandboxAblyAPIKey(withOptions?: object) { + const postData = { + ...testAppSetup.post_apps, + ...(withOptions ?? {}), + }; const response = await fetch('https://sandbox-rest.ably.io/apps', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(testAppSetup.post_apps), + body: JSON.stringify(postData), }); if (!response.ok) { diff --git a/test/package/browser/template/src/tsconfig.json b/test/package/browser/template/src/tsconfig.json index e280baa6d..b206a6399 100644 --- a/test/package/browser/template/src/tsconfig.json +++ b/test/package/browser/template/src/tsconfig.json @@ -4,7 +4,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "bundler", + "moduleResolution": "node", "jsx": "react-jsx" } } diff --git a/test/package/browser/template/test/lib/package.test.ts b/test/package/browser/template/test/lib/package.test.ts index fc73006f3..8554dd762 100644 --- a/test/package/browser/template/test/lib/package.test.ts +++ b/test/package/browser/template/test/lib/package.test.ts @@ -3,6 +3,7 @@ import { test, expect } from '@playwright/test'; test.describe('NPM package', () => { for (const scenario of [ { name: 'default export', path: '/index-default.html' }, + { name: 'LiveObjects plugin export', path: '/index-liveobjects.html' }, { name: 'modular export', path: '/index-modular.html' }, ]) { test.describe(scenario.name, () => {