0.0.6 • Published 26 days ago

@shopify/app-bridge-testing-library v0.0.6

Weekly downloads
-
License
MIT
Repository
github
Last release
26 days ago

@shopify/app-bridge-testing-library

Join our team and work on libraries like this one.

License: MIT npm version npm bundle size (minified + gzip)

You can use the utilities from Shopify App Bridge Testing Library to help write automated tests for your App Bridge app.

NOTE: This package is still under development. As such, the API might be updated without warning before a stable 1.0.0 release.

Installation

You can install Shopify App Bridge Testing Library by using Yarn:

yarn add --dev @shopify/app-bridge-testing-library

Usage

Utilities

createTestApp

Creates a test App Bridge app.

import {createTestApp} from '@shopify/app-bridge-testing-library';

const app = createTestApp();

app.actions

List of actions dispatched by the App Bridge client.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {create, Action, Toast} from '@shopify/app-bridge/actions/Toast';

const app = createTestApp();

const toast = create(app, {
  message: 'Message sent',
  isError: true,
  duration: 5000,
});
toast.dispatch(Action.SHOW);

app.actions[app.actions.length - 1];
/**
{
  "payload": {
    "group": "Toast",
    "payload": {
      "id": "8d95050a-7640-0555-97ea-76b1a56a9580",
      "duration": 5000,
      "isError": true,
      "message": "Message sent"
    },
    "type": "APP::TOAST::SHOW",
    "version": "2.0.21",
    "clientInterface": {
      "name": "@shopify/app-bridge",
      "version": "2.0.21"
    }
  },
  "source": {
    "apiKey": "test",
    "host": "µë-",
    "forceRedirect": false
  },
  "type": "dispatch"
}
*/

app.dispatchFromHost(action, payload?)

Simulates a message from the App Bridge host.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {create, Action, Toast} from '@shopify/app-bridge/actions/Toast';

const app = createTestApp();

const onClear = jest.fn();
app.subscribe(Toast.Action.CLEAR, onClear);

await app.dispatchFromHost(Toast.Action.CLEAR);

expect(onClear).toHaveBeenCalled();

Simulates a message from the App Bridge host for a specific action instance.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {Toast} from '@shopify/app-bridge/actions';

const app = createTestApp();
const payload = {
  message: 'Message sent',
  isError: true,
  duration: 5000,
};

const onClear = jest.fn();
const toast = Toast.create(app, payload);

toast.subscribe(Toast.Action.CLEAR, onClear);

await app.dispatchFromHost(Toast.Action.CLEAR, {payload: {id: toast.id}});

expect(onClear).toHaveBeenCalled();

app.enableFeatures(...features)

Enables available features to the app.featuresAvailable callback to test happy paths.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {Features, Group, Toast} from '@shopify/app-bridge/actions';

const app = createTestApp();

app.subscribe(Features.Action.UPDATE, async function () {
  const features = await app.featuresAvailable(Group.Toast);
  expect(features?.Toast[Toast.Action.SHOW].Dispatch).toBe(true);
});

await app.enableFeatures(Group.Toast).dispatchFromHost(Features.Action.UPDATE);

app.disableFeatures(...features)

Disables available features to the app.featuresAvailable callback to test error states.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {Features, Group, Toast} from '@shopify/app-bridge/actions';

const app = createTestApp();

app.subscribe(Features.Action.UPDATE, async function () {
  const features = await app.featuresAvailable(Group.Toast);
  expect(features?.Toast[Toast.Action.SHOW].Dispatch).toBe(false);
});

await app.disableFeatures(Group.Toast).dispatchFromHost(Features.Action.UPDATE);

app.setState(partialState) (?)

It allows you to mock the App Bridge state returned from the host.

import {createTestApp} from '@shopify/app-bridge-testing-library';

const app = createTestApp();
const state = {
  root: {
    nested: 'value',
    double: {
      nested: 'value',
    },
  },
  nullish: null,
};

app.setState(state);

const noQuery = app.getState();
const nullQuery = app.getState(null);
const rootQuery = app.getState('root');
const nullishQuery = app.getState('nullish');
const nestedQuery = app.getState('root.nested');
const doubleNestedQuery = app.getState('root.double.nested');
const inexistentRootQuery = app.getState('inexistent');
const inexistentNestedQuery = app.getState('some.random.nested.query');
const invalidQuery = app.getState(1234);

expect(await noQuery).toMatchObject(state);
expect(await nullQuery).toMatchObject(state);
expect(await rootQuery).toEqual(state.root);
expect(await nullishQuery).toEqual(state.nullish);
expect(await nestedQuery).toEqual(state.root.nested);
expect(await doubleNestedQuery).toEqual(state.root.double.nested);
expect(await inexistentRootQuery).toBeUndefined();
expect(await inexistentNestedQuery).toBeUndefined();
expect(await invalidQuery).toBeUndefined();

toHaveDispatched(actionType) matcher

It expects that an App Bridge test app has dispatched an action.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {Toast} from '@shopify/app-bridge/actions';

const app = createTestApp();
const payload = {
  message: 'Message sent',
  isError: true,
  duration: 5000,
};

const toast = Toast.create(app, payload);

toast.dispatch(Toast.Action.SHOW);

expect(app).toHaveDispatched(Toast.Action.SHOW);

toHaveDispatchedWith(actionType, actionPayload) matcher

It expects that an App Bridge test app has emitted an action with a given payload.

import {createTestApp} from '@shopify/app-bridge-testing-library';
import {Toast} from '@shopify/app-bridge/actions';

const app = createTestApp();
const payload = {
  message: 'Message sent',
  isError: true,
  duration: 5000,
};

const toast = Toast.create(app, payload);

toast.dispatch(Toast.Action.SHOW);

expect(app).toHaveDispatchedWith(Toast.Action.SHOW, payload);