Skip to content
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

tests: handwrite the bad promise polyfill #11190

Closed
wants to merge 25 commits into from

Conversation

paulirish
Copy link
Member

@paulirish paulirish commented Jul 30, 2020

discussion here: https://github.com/GoogleChrome/lighthouse/pull/11043/files#r448038184

aggressive-promise-polyfill is annoying because of its third_party-ness and no good place to put it.
so we're replacing it with a handwritten one.

i updated the Lighthouse Lore of this in the comments of the polyfill file.

Also, I found 5 cases where we were using potentially-modified version of Promise/Error constructors. We're unaware of any problems arising from that, but it was an easy fix to use the safe versions.


edit (sept 8 2021): see also the polyfill changes from #12932

@paulirish paulirish requested a review from a team as a code owner July 30, 2020 01:45
@paulirish paulirish requested review from Beytoven and removed request for a team July 30, 2020 01:45
@@ -148,9 +148,12 @@ function collectImageElementInfo() {
*/
/* istanbul ignore next */
function determineNaturalSize(url) {
return new Promise((resolve, reject) => {
// @ts-expect-error nativePromise installed by driver.cacheNatives()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oof, do we lose all typechecking of promise types with this? can we

declare global {
  interface Window {
    __nativePromise: typeof Promise
  }
}

or something to make it work?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def this, if we don't do what I suggest in my comment above.

*/

/**
* Lighthouse backstory:

This comment was marked as resolved.

@@ -46,7 +46,7 @@ function installMediaListener() {
*/
/* istanbul ignore next */
function collectTagsThatBlockFirstPaint() {
return new Promise((resolve, reject) => {
return new __nativePromise((resolve, reject) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really awful DX, and ripe for errors (proof is that you found 5 cases where we missed this!)

What if, in Driver.evaluateAsync, we did something like...

(() => {
  var Promise = __nativePromise;
  var Error = __nativeError;
  (${pageFunCode})();
})();

ie. create a scope where we define Promise, Error, etc. vars, so any code we pass in will resolve to these variables over the global objects?

(not in this PR, but I could follow up...)

wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already do this for URL, I'm not sure we should split into another PR when this is the first PR that even starts using these outside driver in the first place.

looks like @paulirish already agrees this is a good idea, how do you feel about reverting these changes and typedefs in favor of connor's suggestion? (if they're necessary to land I guess we can't split, but if they were just gravy on top, revert only?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patrick sorted out the native Promise stuff in #12381

This also completes the colocation of all the cached native definition and usage (except ElementMatches), so no need to reference window.__nativePromise ever again :D

@@ -148,9 +148,12 @@ function collectImageElementInfo() {
*/
/* istanbul ignore next */
function determineNaturalSize(url) {
return new Promise((resolve, reject) => {
// @ts-expect-error nativePromise installed by driver.cacheNatives()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def this, if we don't do what I suggest in my comment above.

@paulirish
Copy link
Member Author

Inspired by the changes and comment in #12932 I resurrected this badboy and addressed all comments

@connorjclark
Copy link
Collaborator

We'll need an alternative to dbw triggering unminified-javascript

Co-authored-by: Patrick Hulce <patrick.hulce@gmail.com>
Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, this PR was so old, it was below the fold with its new label 😅

LGTM! I assume you commented out our workaround and things fail?

the `prepareStackTrace` API. https://github.com/GoogleChrome/lighthouse/issues/1194
However, since https://github.com/GoogleChrome/lighthouse/pull/5509,
we haven't used that API. So, no need to replicate the problem anymore. This comment only remains
as documentation for the legacy __nativeError.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we even need that? feels like a comment on this PR that removes it could suffice :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg. i moved it to #5509

@@ -158,7 +158,8 @@ function collectImageElementInfo() {
function determineNaturalSize(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener('error', _ => reject(new Error('determineNaturalSize failed img load')));
img.addEventListener('error', _ =>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems unrelated?

@connorjclark
Copy link
Collaborator

There's a lot of deltas in the sample artifacts json / lhr that relied on that giant file to provide some results. And so without it, we're left with a lot of passing audits where it was formerly failing. In other words, we lose some bit of coverage here.

Any thing in our node_modules (node_modules/angular/angular.js?) we could replace it with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants