Spectacular prerelease v0.5 supports standalone feature tests and uses partial Ivy compilation
Tags: opensource, angular, testing, spectacular
Published: 2022-08-10 18:53:38

---
title: Spectacular prerelease v0.5 supports standalone feature tests and uses partial Ivy compilation
published: true
description: Standalone feature test provider, partial Ivy compilation, and requirement for at least Angular 12 in Spectacular prerelease version 0.5.0.
tags: opensource,angular,testing,spectacular
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eu6yycytwjs4a2j28t6p.png
# Use a ratio of 100:42 for best results.
---

*Cover art by DALL-E.*

In July 2022, we [published the version 0.5.0 of Spectacular](https://github.com/ngworker/ngworker/releases/tag/spectacular-v0.5.0), the integration testing library for Angular.

> Note that for prerelase versions, that is versions <1.0.0, minor version increases indicate breaking changes, for example releasing version 0.4.0 introduces at least one breaking change compared to version 0.3.0. Patch version increases for prerelease versions indicate bugfixes, refactors, performance improvements, and/or feature additions.

Let's discuss the features and breaking changes of these versions.

## Partial Ivy compilation
Spectacular version 0.1.0-0.4.0 are compiled as View Engine-compatible bundles requiring the Angular Compatibility Compiler (NGCC) to be consumed.

As of version 0.5.0, Spectacular is partially Ivy compiled as is the recommended practice for Angular libraries targeting Angular <=12.2.0. Starting with the future Angular version that removes NGCC, View Engine-compatible libraries stop working.

The partial compilation is a performance improvement as most of the library is compiled before being published to a package registry. However, component templates are still required to be compiled in the context of an application.

To use partial Ivy compilation, Spectacular version 0.5.0 requires at least Angular 12.

## Standalone feature test provider
With the introduction of standalone Angular components and other standalone Angular APIs starting in Angular version 14 where standalone APIs are considered in *developer preview*, we start exposing standalone APIs in Spectacular.

Spectacular's first standalone API is a standalone provider factory for Spectacular's Feature testing API.

Spectacular version 0.5.0 introduces [`provideSpectacularFeatureTest`](https://ngworker.github.io/ngworker/docs/api/modules#providespectacularfeaturetest) that configures the feature-aware navigation services [`SpectacularFeatureLocation`](https://ngworker.github.io/ngworker/docs/api/classes/SpectacularFeatureLocation) and [`SpectacularFeatureRouter`](https://ngworker.github.io/ngworker/docs/api/classes/SpectacularFeatureRouter) for standalone Angular features.

Feature testing a standalone Angular feature using Angular Testing Library and Spectacular:
```typescript
import {
  provideSpectacularFeatureTest,
  SpectacularAppComponent,
  SpectacularFeatureLocation,
  SpectacularFeatureRouter,
} from '@ngworker/spectacular';
import { render, screen } from '@testing-library/angular';
import { Matcher } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { crisisCenterPath } from '@tour-of-heroes/crisis-center';

const findCrisisCenterHomeGreeting = () =>
  screen.findByText(/welcome to the crisis center/i);
const findCrisisLink = (name: Exclude<Matcher, number>) =>
  screen.findByRole('link', {
    name,
  });
const findNameControl = () => screen.findByPlaceholderText(/name/i);
const findSaveButton = () =>
  screen.findByRole('button', { name: /save/i });
const findSelectedCrisis = (name: Matcher) =>
  screen.findByText(name, {
    selector: '.selected a',
  });
const setup = async () => {
  const user = userEvent.setup();
  const {
    fixture: {
      debugElement: { injector },
    },
  } = await render(SpectacularAppComponent, {
    providers: [
      provideSpectacularFeatureTest({
        featurePath: crisisCenterPath,
      }),
    ],
  });

  return {
    location: injector.get(SpectacularFeatureLocation),
    router: injector.get(SpectacularFeatureRouter),
    user,
  };
};

it('Edit crisis from crisis detail', async () => {
  const { location, router, user } = await setup();
  const crisisId = 2;
  await router.navigate(['~', crisisId]);

  await user.clear(await findNameControl());
  await user.type(
    await findNameControl(),
    'The global temperature is rising'
  );
  await user.click(await findSaveButton());

  expect(
    await findSelectedCrisis(/the global temperature is rising/i)
  ).toBeInTheDocument();
  expect(location.path()).toBe(`~/;id=${crisisId};foo=foo`);
});

it('Edit crisis from crisis center home', async () => {
  const { router, user } = await setup();
  await router.navigateByUrl('~/');

  await user.click(
    await findCrisisLink(/procrastinators meeting delayed again/i)
  );

  await user.clear(await findNameControl());
  await user.type(await findNameControl(), 'Coral reefs are dying');
  await user.click(await findSaveButton());

  expect(await findCrisisCenterHomeGreeting()).toBeInTheDocument();
  expect(
    await findSelectedCrisis(/coral reefs are dying/i)
  ).toBeInTheDocument();
});

```

Comparing the previous example to the following code snippet, the difference is in the `setup` [SIFERS](https://medium.com/@kolodny/testing-with-sifers-c9d6bb5b362) where we use [`provideSpectacularFeatureTest`](https://ngworker.github.io/ngworker/docs/api/modules#providespectacularfeaturetest) instead of [`SpectacularFeatureTestingModule`](https://ngworker.github.io/ngworker/docs/api/classes/SpectacularFeatureTestingModule) to adjust the options configuring Angular Testing Library's [`render`](https://testing-library.com/docs/angular-testing-library/api#render) function.

Feature test setup [SIFERS](https://medium.com/@kolodny/testing-with-sifers-c9d6bb5b362) for an Angular feature module using Angular Testing Library and Spectacular:
```typescript
import {
  SpectacularAppComponent,
  SpectacularFeatureLocation,
  SpectacularFeatureRouter,
  SpectacularFeatureTestingModule,
} from '@ngworker/spectacular';
import { render } from '@testing-library/angular';
import userEvent from '@testing-library/user-event';
import {
  CrisisCenterModule,
  crisisCenterPath,
} from '@tour-of-heroes/crisis-center';

const setup = async () => {
  const user = userEvent.setup();
  const {
    fixture: {
      debugElement: { injector },
    },
  } = await render(SpectacularAppComponent, {
    imports: [
      SpectacularFeatureTestingModule.withFeature({
        featureModule: CrisisCenterModule,
        featurePath: crisisCenterPath,
      }),
    ],
  });

  return {
    location: injector.get(SpectacularFeatureLocation),
    router: injector.get(SpectacularFeatureRouter),
    user,
  };
};
```

See [the source code for Spectacular](https://github.com/ngworker/ngworker/tree/main/packages/spectacular) for more examples using the feature testing API or visit  [our documentation](https://ngworker.github.io/ngworker/docs/feature-testing).