Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
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
44 changes: 44 additions & 0 deletions .github/workflows/approve-ssr-golden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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
- 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
2 changes: 1 addition & 1 deletion src/universal-app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
bottom: 100vh !important;
}
.cdk-overlay-backdrop::after {
content: 'OVERLAY ACTIVE';
content: 'OVERLAY ACTIVDE';
background: lime;
}
</style>
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
2 changes: 2 additions & 0 deletions 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
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