Skip to content
Closed
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4cb9377
build: add screenshot test for server-side prerendering
devversion Jun 18, 2021
7f4e03c
Test
devversion Jun 21, 2021
1b2ac82
Test 3
devversion Jun 22, 2021
338018a
ds
devversion Jun 22, 2021
068a0c2
ds
devversion Jun 22, 2021
054a10a
ds
devversion Jun 22, 2021
cff4455
ds
devversion Jun 22, 2021
1a0953b
ds
devversion Jun 22, 2021
4753a99
ds
devversion Jun 22, 2021
7c2d995
ds
devversion Jun 22, 2021
176159e
ds
devversion Jun 22, 2021
afa28b3
ds
devversion Jun 22, 2021
76da46e
ds
devversion Jun 22, 2021
973ab41
ds
devversion Jun 22, 2021
05d01bf
ds
devversion Jun 22, 2021
4528d14
ds
devversion Jun 23, 2021
d9d35b3
dsd
devversion Jun 23, 2021
65dac64
dsd
devversion Jun 23, 2021
70e8d9c
dsd
devversion Jun 23, 2021
ef4aa57
dsd
devversion Jun 23, 2021
e50145e
dsd
devversion Jun 23, 2021
6ea65e4
dsd
devversion Jun 23, 2021
ffb570a
dsd
devversion Jun 23, 2021
3dd3901
ds
devversion Jun 23, 2021
3382e46
ds
devversion Jun 23, 2021
fc0f5e9
ds
devversion Jun 23, 2021
2e3ef2f
Update approve-ssr-golden.yml
devversion Jun 23, 2021
a7f7b43
Update approve-ssr-golden.yml
devversion Jun 23, 2021
1feda96
Update approve-ssr-golden.yml
devversion Jun 23, 2021
2ae4aee
ds
devversion Jun 23, 2021
52c599c
Update approve-ssr-golden.yml
devversion Jun 23, 2021
d91456f
Update approve-ssr-golden.yml
devversion Jun 23, 2021
5d3b6e9
ds
devversion Jun 24, 2021
8bdd24d
ds
devversion Jun 24, 2021
8c3d369
ds
devversion Jun 24, 2021
ace133c
ds
devversion Jun 24, 2021
4ede959
Update kitchen-sink.html
devversion Jun 24, 2021
d976cc1
test: update kitchen-sink prerender screenshot golden
Jun 24, 2021
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
6 changes: 3 additions & 3 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ build:remote --auth_enabled=true
# is provided by the shared dev-infra package and targets k8 remote containers.
build:remote --crosstool_top=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain_suite
build:remote --extra_toolchains=@npm//@angular/dev-infra-private/bazel/remote-execution/cpp:cc_toolchain
build:remote --extra_execution_platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
build:remote --host_platform=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
build:remote --platforms=@npm//@angular/dev-infra-private/bazel/remote-execution:platform
build:remote --extra_execution_platforms=//tools:rbe_platform_with_increased_shared_memory
build:remote --host_platform=//tools:rbe_platform_with_increased_shared_memory
build:remote --platforms=//tools:rbe_platform_with_increased_shared_memory

################################
# --config=build-results #
Expand Down
11 changes: 4 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,12 @@ commands:
description: Checkout and rebase the repository
steps:
- checkout
- run:
name: Set up environment
environment:
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
command: ./.circleci/env.sh
# After checkout, rebase on top of target branch.
- run:
name: Rebase PR on target branch
# After checkout, rebase on top of target branch.
environment:
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
command: |
if [ -n "$CIRCLE_PR_NUMBER" ]; then
# User is required for rebase.
Expand Down
14 changes: 12 additions & 2 deletions .circleci/rebase-pr.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,18 @@ function getRefAndShas(sha, owner, name) {

/** Gets the refs and shas for the base and target of the current environment. */
function getRefsAndShasForChange() {
const base = getRefAndShas(process.env['CI_GIT_BASE_REVISION'], process.env['CI_REPO_OWNER'], process.env['CI_REPO_NAME']);
const target = getRefAndShas(process.env['CI_GIT_REVISION'], process.env['CI_PR_USERNAME'], process.env['CI_PR_REPONAME']);
const base = getRefAndShas(
process.env['CIRCLE_GIT_BASE_REVISION'],
process.env['CIRCLE_PROJECT_USERNAME'],
process.env['CIRCLE_PROJECT_REPONAME']
);

const target = getRefAndShas(
process.env['CIRCLE_GIT_REVISION'],
process.env['CIRCLE_PR_USERNAME'],
process.env['CIRCLE_PR_REPONAME']
);

const commonAncestorSha = getCommonAncestorSha(base.sha, target.sha);
return {
base,
Expand Down
46 changes: 46 additions & 0 deletions .github/workflows/approve-ssr-golden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Approve SSR screenshot golden

on:
pull_request_review:
types: [submitted]

permissions:
pull-requests: write
contents: write

jobs:
ssr_golden_approval:
runs-on: ubuntu-latest
# Run only if the `/approve-ssr-golden` command is specified in the review.
# Skip this job if the comment author is not the author of the pull request.
if: |
contains(github.event.review.body, '/approve-ssr-golden') &&
(github.event.review.author_association == 'COLLABORATOR' ||
github.event.review.author_association == 'MEMBER' ||
github.event.review.author_association == 'OWNER' ||
github.event.review.user.login == github.event.pull_request.user.login
)
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Retrieving pull request head refspec
uses: actions/github-script@v4
id: pr-refspec
with:
result-encoding: string
script: |
const {data} = await github.pulls.get(
{...context.repo, pull_number: ${{github.event.pull_request.number}}});
const repoGitUrl = `github.com/${data.head.repo.full_name}.git`;
return `http://ng-robot:${{secrets.GITHUB_TOKEN}}@${repoGitUrl} HEAD:${data.head.ref}`;
- run: yarn install --frozen-lockfile --non-interactive
- run: bazel run //src/universal-app:screenshot_test.accept
- name: Push back to pull request
env:
TARGET_REFSPEC: ${{steps.pr-refspec.outputs.result}}
run: |
git config --global user.name 'ng-github-robot'
git config --global user.email '[email protected]'
git commit -am "test: update kitchen-sink prerender screenshot golden"
git push ${TARGET_REFSPEC}
1 change: 1 addition & 0 deletions goldens/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
exports_files([
"size-test.yaml",
"kitchen-sink-prerendered.png",
])
Binary file added goldens/image-diff.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added goldens/kitchen-sink-prerendered.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added goldens/linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
"@types/googlemaps": "^3.43.1",
"@types/youtube": "^0.0.42",
"core-js-bundle": "^3.8.2",
"fast-png": "^5.0.4",
"material-components-web": "12.0.0-canary.2952c6a76.0",
"pixelmatch": "^5.2.1",
"rxjs": "^6.5.3",
"rxjs-tslint-rules": "^4.33.1",
"systemjs": "0.19.43",
Expand Down Expand Up @@ -204,6 +206,7 @@
"parse5": "^6.0.1",
"postcss": "^8.2.1",
"protractor": "^7.0.0",
"puppeteer-core": "^10.0.0",
"reflect-metadata": "^0.1.3",
"requirejs": "^2.3.6",
"rollup": "~2.42.2",
Expand Down
34 changes: 29 additions & 5 deletions src/universal-app/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load("//src/cdk-experimental:config.bzl", "CDK_EXPERIMENTAL_TARGETS")
load("//src/material:config.bzl", "MATERIAL_TARGETS")
load("//src/material-experimental:config.bzl", "MATERIAL_EXPERIMENTAL_TARGETS")
load("//tools:defaults.bzl", "ng_module", "sass_binary", "ts_library")
load(":ssr-screenshot-test.bzl", "ssr_screenshot_test")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -53,13 +54,36 @@ sass_binary(
],
)

nodejs_test(
name = "server_test",
data = [
"index.html",
prerenderStaticAssets = [
"index.html",
":theme_scss",
]

ts_library(
name = "ssr_screenshot_test_lib",
testonly = True,
srcs = ["ssr-screenshot-test-runner.ts"],
deps = [
":server",
":theme_scss",
"@npm//@bazel/runfiles",
"@npm//@types/node",
"@npm//@types/selenium-webdriver",
"@npm//fast-png",
"@npm//pixelmatch",
"@npm//puppeteer-core",
],
)

# Screenshot test that compares the pre-rendered universal-app against the golden.
ssr_screenshot_test(
name = "screenshot_test",
data = prerenderStaticAssets,
golden = "//goldens:kitchen-sink-prerendered.png",
)

nodejs_test(
name = "server_test",
data = [":server"] + prerenderStaticAssets,
entry_point = ":prerender.ts",
templated_args = [
# TODO(josephperrott): update dependency usages to no longer need bazel patch module resolver
Expand Down
4 changes: 3 additions & 1 deletion src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<h1>MDC implementation</h1>

<h2>Autocomplete</h2>
<mat-autocomplete>
<mat-option>Grace Hopper</mat-option>
<mat-option>Grace Hdopper</mat-option>
<mat-option>Anita Borg</mat-option>
<mat-option>Ada Lovelace</mat-option>
</mat-autocomplete>
Expand Down
9 changes: 7 additions & 2 deletions src/universal-app/kitchen-sink-mdc/kitchen-sink-mdc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import {MatSelectModule} from '@angular/material-experimental/mdc-select';
import {MatPaginatorModule} from '@angular/material-experimental/mdc-paginator';

@Component({
template: `<button>Do the thing</button>`
template: `
<mat-dialog-content>
<button>MDC dialog</button>
</mat-dialog-content>
`,
})
export class TestEntryComponent {}

Expand All @@ -32,7 +36,8 @@ export class TestEntryComponent {}
})
export class KitchenSinkMdc {
constructor(dialog: MatDialog) {
dialog.open(TestEntryComponent);
// The MDC component is on the right, so we show the MDC dialog on the right too.
dialog.open(TestEntryComponent, {position: {top: '0', right: '0'}});
}
}

Expand Down
29 changes: 26 additions & 3 deletions src/universal-app/kitchen-sink-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,33 @@ import {KitchenSinkModule} from './kitchen-sink/kitchen-sink';
@Component({
selector: 'kitchen-sink-root',
template: `
<h1>Kitchen sink app</h1>
<kitchen-sink></kitchen-sink>
<kitchen-sink-mdc></kitchen-sink-mdc>
<div class="kitchen-sink-row">
<kitchen-sink class="kitchen-sink"></kitchen-sink>
<kitchen-sink-mdc class="kitchen-sink"></kitchen-sink-mdc>
</div>
`,
styles: [`
/**
Align both components (the non-MDC and MDC kitchen-sinks) next to each other.
This reduces the overall height of the page and makes it easier to capture
in screenshot tests where browsers (even headless ones) seem to have a limit.
*/
.kitchen-sink-row {
display: flex;
flex-direction: row;
}

/** Add padding for the kitchen-sink components, and expand them equally in the row. */
.kitchen-sink {
flex: 1;
padding: 16px;
}

/** The first kitchen-sink should have a border to split up the two components visually. */
.kitchen-sink:first-child {
border-right: 2px solid grey;
}
`]
})
export class KitchenSinkRoot {
}
Expand Down
4 changes: 3 additions & 1 deletion src/universal-app/kitchen-sink/kitchen-sink.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<h1>Standard implementation (non-MDC)</h1>

<h2>Autocomplete</h2>
<mat-autocomplete>
<mat-option>Grace Hopper</mat-option>
Expand Down Expand Up @@ -41,7 +43,7 @@ <h3>Standalone</h3>
<h3>Card</h3>

<mat-card>
Simple card
Simple card1
</mat-card>

<mat-card>
Expand Down
19 changes: 11 additions & 8 deletions src/universal-app/kitchen-sink/kitchen-sink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class TableDataSource extends DataSource<any> {


@Component({
template: `<button>Do the thing</button>`
template: `<button>Non-MDC dialog</button>`
})
export class TestEntryComponent {}

Expand All @@ -77,15 +77,18 @@ export class KitchenSink {
virtualScrollData = Array(10000).fill(50);

constructor(
snackBar: MatSnackBar,
dialog: MatDialog,
viewportRuler: ViewportRuler,
focusMonitor: FocusMonitor,
elementRef: ElementRef<HTMLElement>,
bottomSheet: MatBottomSheet) {
snackBar: MatSnackBar,
dialog: MatDialog,
viewportRuler: ViewportRuler,
focusMonitor: FocusMonitor,
elementRef: ElementRef<HTMLElement>,
bottomSheet: MatBottomSheet) {
focusMonitor.focusVia(elementRef, 'program');
snackBar.open('Hello there');
dialog.open(TestEntryComponent);
// The non-MDC component is on the left, so we show the dialog on the left side too.
// Since the "overlay active" indicator is on the left top too, we shift the dialog
// to the right a little more (to avoid content overlapping).
dialog.open(TestEntryComponent, {position: {left: '30%', top: '0'}});
bottomSheet.open(TestEntryComponent);

// Do a sanity check on the viewport ruler.
Expand Down
10 changes: 6 additions & 4 deletions src/universal-app/prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@ import {KitchenSinkRootServerModuleNgFactory} from './kitchen-sink-root.ngfactor

// Resolve the path to the "index.html" through Bazel runfile resolution.
const indexHtmlPath = require.resolve('./index.html');
const outputPath = join(__dirname, 'index-prerendered.html');

const result = renderModuleFactory(
KitchenSinkRootServerModuleNgFactory,
{document: readFileSync(indexHtmlPath, 'utf-8')});

result
.then(content => {
const filename = join(__dirname, 'index-prerendered.html');

console.log('Inspect pre-rendered page here:');
console.log(`file://${filename}`);
writeFileSync(filename, content, 'utf-8');
console.log(`file://${outputPath}`);
writeFileSync(outputPath, content, 'utf-8');
console.log('Prerender done.');
})
// If rendering the module factory fails, print the error and exit the process
Expand All @@ -32,3 +31,6 @@ result
console.error(error);
process.exit(1);
});

// Export the output path in case this file is imported as part of a test.
export {outputPath};
Loading