8000 fix(core): properly handle app stabilization with defer blocks [patch] by alan-agius4 · Pull Request #61056 · angular/angular · GitHub
[go: up one dir, main page]

Skip to content

fix(core): properly handle app stabilization with defer blocks [patch] #61056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
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
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ integration/ng_update_migrations/node_modules
integration/ng-add-localize/node_modules
integration/nodenext_resolution/node_modules
integration/platform-server/node_modules
integration/platform-server-zoneless/node_modules
integration/platform-server-hydration/node_modules
integration/service-worker-schema/node_modules
integration/side-effects/node_modules
Expand Down
16 changes: 16 additions & 0 deletions integration/platform-server-zoneless/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single

[*.md]
max_line_length = off
trim_trailing_whitespace = false
42 changes: 42 additions & 0 deletions integration/platform-server-zoneless/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# Compiled output
/dist
/tmp
/out-tsc
/bazel-out

# Node
/node_modules
npm-debug.log
yarn-error.log

# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*

# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings

# System files
.DS_Store
Thumbs.db
6 changes: 6 additions & 0 deletions integration/platform-server-zoneless/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
load("//integration:index.bzl", "ng_integration_test")

ng_integration_test(
name = "test",
setup_chromium = True,
)
27 changes: 27 additions & 0 deletions integration/platform-server-zoneless/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# PlatformServer

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 16.0.0-rc.0.

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.

## Code scaffolding

Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.

## Build

Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.

## Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
110 changes: 110 additions & 0 deletions integration/platform-server-zoneless/angular.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"standalone": {
"projectType": "application",
"schematics": {},
"root": "projects/standalone",
"sourceRoot": "projects/standalone/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"namedChunks": true,
"outputPath": "dist/standalone",
"index": "projects/standalone/src/index.html",
"browser": "projects/standalone/src/main.ts",
"server": "projects/standalone/src/main.server.ts",
"ssr": {
"entry": "projects/standalone/server.ts"
},
"tsConfig": "projects/standalone/tsconfig.app.json",
"assets": [
"projects/standalone/src/favicon.ico",
"projects/standalone/src/assets"
],
"styles": [
"projects/standalone/src/styles.css"
],
"progress": false,
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "standalone:build:production"
},
"development": {
"buildTarget": "standalone:build:development"
}
},
"defaultConfiguration": "development"
},
"e2e": {
"builder": "@angular-devkit/build-angular:private-protractor",
"options": {
"port": 0,
"protractorConfig": "e2e/protractor.conf.js",
"webdriverUpdate": false,
"baseUrl": "http://localhost:4206"
}
},
"extract-i18n": {
"builder": "@angular/build:extract-i18n",
"options": {
"buildTarget": "standalone:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"progress": false,
"tsConfig": "projects/standalone/tsconfig.spec.json",
"assets": [
"projects/standalone/src/favicon.ico",
"projects/standalone/src/assets"
],
"styles": [
"projects/standalone/src/styles.css"
],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": false,
"cache": {
"enabled": false
}
}
}
43 changes: 43 additions & 0 deletions integration/platform-server-zoneless/e2e/protractor.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

Check notice on line 3 in integration/platform-server-zoneless/e2e/protractor.conf.js

View check run for this annotation

In Solidarity / Inclusive Language

Match Found

Please consider an alternative to `master`. Possibilities include: `primary`, `main`, `leader`, `active`, `writer`
Raw output
/master/gi
const {SpecReporter} = require('jasmine-spec-reporter');

/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: ['./src/**/*-spec.ts'],
chromeDriver: process.env.CHROMEDRIVER_BIN,
SELENIUM_PROMISE_MANAGER: false,
capabilities: {
browserName: 'chrome',
chromeOptions: {
binary: process.env.CHROME_BIN,
// See /integration/README.md#browser-tests for more info on these args
args: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--disable-dev-shm-usage',
'--hide-scrollbars',
'--mute-audio',
],
},
},
directConnect: true,
baseUrl: 'http://localhost:4206/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () {},
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json'),
});
jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
},
};
27 changes: 27 additions & 0 deletions integration/platform-server-zoneless/e2e/src/defer-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {browser, by, element} from 'protractor';
import {bootstrapClientApp, navigateTo, verifyNoBrowserErrors} from './util';

describe('Defer E2E Tests', () => {
beforeEach(async () => {
// Don't wait for Angular since it is not bootstrapped automatically.
await browser.waitForAngularEnabled(false);

// Load the page without waiting for Angular since it is not bootstrapped automatically.
await navigateTo('defer');
});

afterEach(async () => {
// Make sure there were no client side errors.
await verifyNoBrowserErrors();
});

it('should text in defered component with input', async () => {
// Test the contents from the server.
expect(await element(by.css('p')).getText()).toEqual('Hydrate Never works!');

await bootstrapClientApp();

// Retest the contents after the client bootstraps.
expect(await element(by.css('p')).getText()).toEqual('Hydrate Never works!');
});
});
38 changes: 38 additions & 0 deletions integration/platform-server-zoneless/e2e/src/helloworld-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {browser, by, element} from 'protractor';
import {bootstrapClientApp, navigateTo, verifyNoBrowserErrors} from './util';

describe('Hello world E2E Tests', () => {
beforeEach(async () => {
// Don't wait for Angular since it is not bootstrapped automatically.
await browser.waitForAngularEnabled(false);

// Load the page without waiting for Angular since it is not bootstrapped automatically.
await navigateTo('helloworld');
});

afterEach(async () => {
// Make sure there were no client side errors.
await verifyNoBrowserErrors();
});

it('should display: Hello world!', async () => {
// Test the contents from the server.
expect(await element(by.css('div')).getText()).toEqual('Hello world!');

await bootstrapClientApp();

// Retest the contents after the client bootstraps.
expect(await element(by.css('div')).getText()).toEqual('Hello world!');
});

it('should re-use component styles rendered on the server', async () => {
expect(await element(by.css('style[ng-app-id="ng"]')).getText()).not.toBeNull();

await bootstrapClientApp();

// Make sure the server styles get reused by the client.
expect(await element(by.css('style[ng-app-id="ng"]')).isPresent()).toBeFalsy();
expect(await element(by.css('style[ng-style-reused]')).isPresent()).toBeTruthy();
expect(await element(by.css('style')).getText()).toBe('');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

import {browser, by, element} from 'protractor';
import {bootstrapClientApp, navigateTo, verifyNoBrowserErrors} from './util';

// TODO: this does not work with zoneless
describe('Http TransferState Lazy On Init', () => {
beforeEach(async () => {
// Don't wait for Angular since it is not bootstrapped automatically.
await browser.waitForAngularEnabled(false);

// Load the page without waiting for Angular since it is not bootstrapped automatically.
await navigateTo('http-transferstate-lazy-on-init');
});

afterEach(async () => {
// Make sure there were no client side errors.
await verifyNoBrowserErrors();
});

it('should transfer http state in lazy component', async () => {
// Test the contents from the server.
expect(await element(by.css('div.one')).getText()).toBe('API 1 response');

// Bootstrap the client side app and retest the contents
await bootstrapClientApp();
expect(await element(by.css('div.one')).getText()).toBe('API 1 response');

// Validate that there were no HTTP calls to '/api'.
const requests = await browser.executeScript(() => {
return performance.getEntriesByType('resource');
});
const apiRequests = (requests as {name: string}[])
.filter(({name}) => name.includes('/api'))
.map(({name}) => name);

expect(apiRequests).toEqual([]);
});
});
Loading
Loading
0