Skip to content
This repository was archived by the owner on Aug 19, 2024. It is now read-only.

Add Angular Tests to Master #23

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ To do a prod build (with AOT):
- `npm run build`

The build artifacts will be stored in the `dist/` directory.


4 changes: 2 additions & 2 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ module.exports = function (config) {
restartOnFileChange: true,
// not strictly required for testing but useful when debugging the grid in action
files: [
'../node_modules/@ag-grid-community/styles/ag-grid.css',
'../node_modules/@ag-grid-community/styles/ag-theme-balham.css'
'./node_modules/@ag-grid-community/styles/ag-grid.css',
'./node_modules/@ag-grid-community/styles/ag-theme-balham.css'
]
});
};
38 changes: 21 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ag-grid-angular-cli-example",
"version": "31.0.2",
"version": "31.1.0",
"description": "AG Grid Angular Example Using Angular CLI",
"license": "MIT",
"repository": {
Expand All @@ -12,24 +12,26 @@
"start": "NODE_OPTIONS=--openssl-legacy-provider ng serve --port 8080",
"build": "NODE_OPTIONS=\"--openssl-legacy-provider --max-old-space-size=8192\" ng build --aot",
"build-prod": "npm run build",
"lint": "tslint \"src/**/*.ts\""
"lint": "tslint \"src/**/*.ts\"",
"test:e2e": "NODE_OPTIONS=--openssl-legacy-provider ./node_modules/.bin/ng test --watch false --browsers ChromeHeadless",
"test:watch": "NODE_OPTIONS=--openssl-legacy-provider ./node_modules/.bin/ng test --watch true --browsers ChromeHeadless"
},
"private": true,
"dependencies": {
"@ag-grid-community/angular": "~31.0.2",
"@ag-grid-community/core": "~31.0.2",
"@ag-grid-community/client-side-row-model": "~31.0.2",
"@ag-grid-enterprise/core": "~31.0.2",
"@ag-grid-enterprise/menu": "~31.0.2",
"@ag-grid-enterprise/side-bar": "~31.0.2",
"@ag-grid-enterprise/column-tool-panel": "~31.0.2",
"@ag-grid-enterprise/filter-tool-panel": "~31.0.2",
"@ag-grid-enterprise/row-grouping": "~31.0.2",
"@ag-grid-enterprise/set-filter": "~31.0.2",
"@ag-grid-enterprise/status-bar": "~31.0.2",
"@ag-grid-enterprise/range-selection": "~31.0.2",
"@ag-grid-enterprise/charts": "~31.0.2",
"@ag-grid-community/styles": "~31.0.2",
"@ag-grid-community/angular": "~31.1.0",
"@ag-grid-community/core": "~31.1.0",
"@ag-grid-community/client-side-row-model": "~31.1.0",
"@ag-grid-enterprise/core": "~31.1.0",
"@ag-grid-enterprise/menu": "~31.1.0",
"@ag-grid-enterprise/side-bar": "~31.1.0",
"@ag-grid-enterprise/column-tool-panel": "~31.1.0",
"@ag-grid-enterprise/filter-tool-panel": "~31.1.0",
"@ag-grid-enterprise/row-grouping": "~31.1.0",
"@ag-grid-enterprise/set-filter": "~31.1.0",
"@ag-grid-enterprise/status-bar": "~31.1.0",
"@ag-grid-enterprise/range-selection": "~31.1.0",
"@ag-grid-enterprise/charts": "~31.1.0",
"@ag-grid-community/styles": "~31.1.0",
"@angular/animations": "^14.3.0",
"@angular/common": "^14.3.0",
"@angular/compiler": "^14.3.0",
Expand All @@ -47,8 +49,10 @@
"@angular-devkit/build-angular": "^14.2.12",
"@angular/cli": "^14.2.12",
"@angular/compiler-cli": "^14.3.0",
"@testing-library/angular": "^12.3.0",
"@testing-library/user-event": "^14.5.2",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"@types/node": "18.19.10",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
Expand Down
4 changes: 2 additions & 2 deletions src/app/rich-grid-example/rich-grid.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ <h1>Rich Grid Example</h1>
</span>
<span style="float: right">
Column API:
<button (click)="this.api.setColumnVisible('country', false)" class="btn btn-primary">Hide Country Column</button>
<button (click)="this.api.setColumnVisible('country', true)" class="btn btn-primary">Show Country Column</button>
<button (click)="this.api.setColumnsVisible(['country'], false)" class="btn btn-primary">Hide Country Column</button>
<button (click)="this.api.setColumnsVisible(['country'], true)" class="btn btn-primary">Show Country Column</button>
</span>
</div>
</div>
Expand Down
38 changes: 17 additions & 21 deletions src/test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import {getTestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;

// Prevent Karma from running prematurely.
__karma__.loaded = function () {
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(), {
teardown: { destroyAfterEach: false }
}
BrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
{ teardown: { destroyAfterEach: true } },
);

// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();
context.keys().map(context);
103 changes: 103 additions & 0 deletions src/tests/ag-grid-angular.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Component, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { GridApi, GridOptions, GridReadyEvent, Module } from '@ag-grid-community/core';
import { AgGridAngular } from '@ag-grid-community/angular';

@Component({
selector: 'app-grid-wrapper',
standalone: true,
imports: [AgGridAngular],
template: `<ag-grid-angular
[gridOptions]="gridOptions"
[columnDefs]="columnDefs"
[rowData]="rowData"
[modules]="modules"
(gridReady)="onGridReady($event)"
[suppressBrowserResizeObserver]="suppressBrowserResizeObserver"
(firstDataRendered)="onFirstDataRendered($event)"></ag-grid-angular>`,
})
export class GridWrapperComponent {
modules: Module[] = [ClientSideRowModelModule];
rowData: any[] | null = null;
columnDefs = [{ field: 'make' }, { field: 'model' }, { field: 'price' }];

gridOptions: GridOptions = {};
gridApi!: GridApi;

suppressBrowserResizeObserver = false;

@ViewChild(AgGridAngular) agGrid!: AgGridAngular;

onGridReady(params: GridReadyEvent) {
this.gridApi = params.api;
// this.gridApi.setGridOption('rowData', [{ make: 'Toyota', model: 'Celica', price: 35000 }]);
this.rowData = [{ make: 'Toyota', model: 'Celica', price: 35000 }];
}
onFirstDataRendered(params: any) {}
}

describe('Grid OnReady', () => {
let component: GridWrapperComponent;
let fixture: ComponentFixture<GridWrapperComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GridWrapperComponent, AgGridAngular],
}).compileComponents();

fixture = TestBed.createComponent(GridWrapperComponent);
component = fixture.componentInstance;
});

it('gridReady is completed by the time a timeout finishes', (done) => {
fixture.detectChanges();
setTimeout(() => {
expect(component.gridApi).toBeDefined();
done();
}, 0);
});

const runGridReadyTest = async () => {
spyOn(component, 'onGridReady').and.callThrough();
spyOn(component, 'onFirstDataRendered').and.callThrough();

fixture.detectChanges();
await fixture.whenStable();

expect(component.gridApi).toBeDefined();

fixture.detectChanges(); // force rowData binding to be applied
await fixture.whenStable();

// If calling the gridApi.setRowData we don't need to call the fixture.detectChanges()

expect(component.onGridReady).toHaveBeenCalled();
expect(component.onFirstDataRendered).toHaveBeenCalled();
};

it('Fixture goes stable and calls gridReady', async () => {
await runGridReadyTest();
});

it('Fixture goes stable even with suppressBrowserResizeObserver= true', async () => {
// Test with the fallback polling to mimic Jest not supporting ResizeObserver
// We must have the polling run outside of the Angular zone
component.suppressBrowserResizeObserver = true;

await runGridReadyTest();
});

it('Grid Ready run Auto', async () => {
spyOn(component, 'onGridReady').and.callThrough();
spyOn(component, 'onFirstDataRendered').and.callThrough();
fixture.autoDetectChanges();
await fixture.whenStable();

expect(component.gridApi).toBeDefined();

expect(component.onGridReady).toHaveBeenCalled();
expect(component.onFirstDataRendered).toHaveBeenCalled();
});
});
46 changes: 46 additions & 0 deletions src/tests/clickingRows.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component } from '@angular/core';

import { render, screen } from '@testing-library/angular';
import userEvent from '@testing-library/user-event';

import { AgGridAngular } from '@ag-grid-community/angular';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import { ColDef, GridOptions, ModuleRegistry } from '@ag-grid-community/core';

ModuleRegistry.register(ClientSideRowModelModule);

@Component({
selector: 'app-grid-wrapper',
standalone: true,
imports: [AgGridAngular],
template: `<div data-testid="rowClicked">Row Clicked: {{ rowClicked?.make }}</div>
<ag-grid-angular [gridOptions]="gridOptions" [columnDefs]="columnDefs" [rowData]="rowData"> </ag-grid-angular>`,
})
export class GridWrapperComponent {
rowData: any[] = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 },
];
columnDefs: ColDef[] = [{ field: 'make' }, { field: 'model' }, { field: 'price' }];
rowClicked: any;

gridOptions: GridOptions = {
onRowClicked: (params) => {
this.rowClicked = params.data;
},
};
}

describe('Test Row Clicked', () => {
it('Test cell clicked run row handler', async () => {
render(GridWrapperComponent);

const row = await screen.findByText('Ford');

await userEvent.click(row);

const rowClicked = await screen.findByTestId('rowClicked');
expect(rowClicked.textContent).toBe('Row Clicked: Ford');
});
});
Loading