Skip to content

Commit bb3417b

Browse files
committed
feat: remove removeAngularAttributes
1 parent 44167af commit bb3417b

File tree

7 files changed

+24
-109
lines changed

7 files changed

+24
-109
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ jobs:
3636
run: npm install --force
3737
- name: build
3838
run: npm run build -- --skip-nx-cache
39+
timeout-minutes: 5
3940
- name: test
4041
run: npm run test
42+
timeout-minutes: 5
4143
- name: lint
4244
run: npm run lint
45+
timeout-minutes: 5
4346
- name: Release
4447
if: github.repository == 'testing-library/angular-testing-library' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta')
4548
run: npx semantic-release

projects/testing-library/src/lib/models.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -451,20 +451,6 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
451451
*/
452452
initialRoute?: string;
453453

454-
/**
455-
* @description
456-
* Removes the Angular attributes (ng-version, and root-id) from the fixture.
457-
*
458-
* @default
459-
* `false`
460-
*
461-
* @example
462-
* await render(AppComponent, {
463-
* removeAngularAttributes: true
464-
* })
465-
*/
466-
removeAngularAttributes?: boolean;
467-
468454
/**
469455
* @description
470456
* Callback to configure the testbed before the compilation.

projects/testing-library/src/lib/testing-library.ts

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Type,
1313
isStandalone,
1414
Binding,
15+
ApplicationRef,
1516
} from '@angular/core';
1617
import { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed, tick } from '@angular/core/testing';
1718
import { NavigationExtras, Router } from '@angular/router';
@@ -76,7 +77,6 @@ export async function render<SutType, WrapperType = SutType>(
7677
componentImports,
7778
excludeComponentDeclaration = false,
7879
routes = [],
79-
removeAngularAttributes = false,
8080
defaultImports = [],
8181
initialRoute = '',
8282
deferBlockStates = undefined,
@@ -226,30 +226,15 @@ export async function render<SutType, WrapperType = SutType>(
226226
subscribedOutputs = subscribeToComponentOutputs(createdFixture, subscribeTo);
227227
}
228228

229-
if (removeAngularAttributes) {
230-
createdFixture.nativeElement.removeAttribute('ng-version');
231-
const idAttribute = createdFixture.nativeElement.getAttribute('id');
232-
if (idAttribute?.startsWith('root')) {
233-
createdFixture.nativeElement.removeAttribute('id');
234-
}
235-
}
236-
237229
mountedFixtures.add(createdFixture);
238230

239-
let isAlive = true;
240-
createdFixture.componentRef.onDestroy(() => {
241-
isAlive = false;
242-
});
243-
244231
if (hasOnChangesHook(createdFixture.componentInstance) && Object.keys(properties).length > 0) {
245232
const changes = getChangesObj(null, componentProperties);
246233
createdFixture.componentInstance.ngOnChanges(changes);
247234
}
248235

249236
detectChanges = () => {
250-
if (isAlive) {
251-
createdFixture.detectChanges();
252-
}
237+
safeDetectChanges(createdFixture);
253238
};
254239

255240
if (detectChangesOnRender) {
@@ -634,26 +619,13 @@ async function waitForElementToBeRemovedWrapper<T>(
634619
}
635620

636621
function cleanup() {
637-
mountedFixtures.forEach(cleanupAtFixture);
638-
}
639-
640-
function cleanupAtFixture(fixture: ComponentFixture<any>) {
641-
fixture.destroy();
642-
643-
if (!fixture.nativeElement.getAttribute('ng-version') && fixture.nativeElement.parentNode === document.body) {
644-
document.body.removeChild(fixture.nativeElement);
645-
} else if (!fixture.nativeElement.getAttribute('id') && document.body.children?.[0] === fixture.nativeElement) {
646-
document.body.removeChild(fixture.nativeElement);
647-
}
648-
649-
mountedFixtures.delete(fixture);
622+
mountedFixtures.clear();
650623
}
651624

652625
// if we're running in a test runner that supports afterEach
653626
// then we'll automatically run cleanup afterEach test
654627
// this ensures that tests run in isolation from each other
655628
// if you don't like this, set the ATL_SKIP_AUTO_CLEANUP env variable to 'true'
656-
declare const afterEach: any;
657629
if (typeof process === 'undefined' || !process?.env?.['ATL_SKIP_AUTO_CLEANUP']) {
658630
if (typeof afterEach === 'function') {
659631
afterEach(() => {
@@ -690,12 +662,19 @@ function replaceFindWithFindAndDetectChanges<T extends Record<string, any>>(orig
690662
*/
691663
function detectChangesForMountedFixtures() {
692664
for (const fixture of mountedFixtures) {
693-
try {
665+
safeDetectChanges(fixture);
666+
}
667+
}
668+
669+
function safeDetectChanges<T>(fixture: ComponentFixture<T>) {
670+
try {
671+
const appRef = fixture.componentRef.injector.get(ApplicationRef);
672+
if (!appRef.destroyed) {
694673
fixture.detectChanges();
695-
} catch (err: any) {
696-
if (!err.message.startsWith('ViewDestroyedError')) {
697-
throw err;
698-
}
674+
}
675+
} catch (err: any) {
676+
if (!err.message.startsWith('ViewDestroyedError') && !err.message.startsWith('NG0205')) {
677+
throw err;
699678
}
700679
}
701680
}

projects/testing-library/src/tests/auto-cleanup.spec.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class FixtureComponent {
1010
@Input() name = '';
1111
}
1212

13-
describe('Angular auto clean up - previous components only get cleanup up on init (based on root-id)', () => {
13+
describe('Angular auto clean up - previous components only get cleanup up on init', () => {
1414
test('first', async () => {
1515
await render(FixtureComponent, {
1616
componentProperties: {
@@ -28,15 +28,3 @@ describe('Angular auto clean up - previous components only get cleanup up on ini
2828
expect(document.body.innerHTML).not.toContain('first');
2929
});
3030
});
31-
32-
describe('ATL auto clean up - after each test the containers get removed', () => {
33-
test('first', async () => {
34-
await render(FixtureComponent, {
35-
removeAngularAttributes: true,
36-
});
37-
});
38-
39-
test('second', () => {
40-
expect(document.body).toBeEmptyDOMElement();
41-
});
42-
});

projects/testing-library/src/tests/issues/issue-398-component-without-host-id.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ test('should re-create the app', async () => {
1313
});
1414

1515
@Component({
16-
selector: 'atl-fixture',
16+
selector: 'atl-fixture-398',
1717
standalone: true,
1818
template: '<h1>My title</h1>',
1919
host: {

projects/testing-library/src/tests/render-template.spec.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,6 @@ test('overrides output properties', async () => {
114114
expect(clicked).toHaveBeenCalledWith('off');
115115
});
116116

117-
describe('removeAngularAttributes', () => {
118-
it('should remove angular attributes', async () => {
119-
await render('<div onOff (clicked)="clicked($event)"></div>', {
120-
imports: [OnOffDirective],
121-
removeAngularAttributes: true,
122-
});
123-
124-
expect(document.querySelector('[ng-version]')).toBeNull();
125-
expect(document.querySelector('[id]')).toBeNull();
126-
});
127-
128-
it('is disabled by default', async () => {
129-
await render('<div onOff (clicked)="clicked($event)"></div>', {
130-
imports: [OnOffDirective],
131-
});
132-
133-
expect(document.querySelector('[ng-version]')).not.toBeNull();
134-
expect(document.querySelector('[id]')).not.toBeNull();
135-
});
136-
});
137-
138117
test('updates properties and invokes change detection', async () => {
139118
const view = await render<{ value: string }>('<div [update]="value" ></div>', {
140119
imports: [UpdateInputDirective],

projects/testing-library/src/tests/render.spec.ts

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -141,26 +141,6 @@ describe('childComponentOverrides', () => {
141141
});
142142
});
143143

144-
describe('removeAngularAttributes', () => {
145-
test('should remove angular attribute', async () => {
146-
await render(FixtureComponent, {
147-
removeAngularAttributes: true,
148-
});
149-
150-
expect(document.querySelector('[ng-version]')).toBeNull();
151-
expect(document.querySelector('[id]')).toBeNull();
152-
});
153-
154-
test('is disabled by default', async () => {
155-
await render(FixtureComponent, {
156-
removeAngularAttributes: false,
157-
});
158-
159-
expect(document.querySelector('[ng-version]')).not.toBeNull();
160-
expect(document.querySelector('[id]')).not.toBeNull();
161-
});
162-
});
163-
164144
describe('componentOutputs', () => {
165145
test('should set passed event emitter to the component', async () => {
166146
@Component({ template: `` })
@@ -184,22 +164,22 @@ describe('componentOutputs', () => {
184164
});
185165

186166
describe('on', () => {
187-
@Component({ template: `` })
167+
@Component({ selector: 'atl-test-fixture-with-event-emitter', template: `` })
188168
class TestFixtureWithEventEmitterComponent {
189169
@Output() readonly event = new EventEmitter<void>();
190170
}
191171

192-
@Component({ template: `` })
172+
@Component({ selector: 'atl-test-fixture-with-derived-event', template: `` })
193173
class TestFixtureWithDerivedEventComponent {
194174
@Output() readonly event = fromEvent<MouseEvent>(inject(ElementRef).nativeElement, 'click');
195175
}
196176

197-
@Component({ template: `` })
177+
@Component({ selector: 'atl-test-fixture-with-functional-output', template: `` })
198178
class TestFixtureWithFunctionalOutputComponent {
199179
readonly event = output<string>();
200180
}
201181

202-
@Component({ template: `` })
182+
@Component({ selector: 'atl-test-fixture-with-functional-derived-event', template: `` })
203183
class TestFixtureWithFunctionalDerivedEventComponent {
204184
readonly event = outputFromObservable(fromEvent<MouseEvent>(inject(ElementRef).nativeElement, 'click'));
205185
}

0 commit comments

Comments
 (0)