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

[Defer Uploads v2] Added support for handling multiple root resource in single asset discovery phase #1728

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

chinmay-browserstack
Copy link
Contributor

@chinmay-browserstack chinmay-browserstack commented Sep 18, 2024

  • Added new endpoints which will return widths from deviceDetails if present and from config settings.
  • Added new config multiDOM which when passed we capture DOM in all widths in which it will be rendered.
  • Changed structure of domSnapshot. now domSnapshot can also be a list of objects with following strucuture { 'domSnapshot': <DOM>, 'width': <int>}
  • Resources map will now contain list of root resources. if multiple root resources are present.
  • getResource will return root resource based on width on which discovery browser is opened. in case root resource not present for that width we will fallback to first dom in list.
  • re load page in case of multiDOM. since root resource will only get updated in we re load the page.
  • disable captureSrcset if multiDOM is enabled.

let allResources = new Set();

if (!Array.isArray(domSnapshot)) {
domSnapshot = [{ domSnapshot }];
Copy link
Contributor

@ninadbstack ninadbstack Sep 19, 2024

Choose a reason for hiding this comment

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

should this be an object array with domSnapshot key i it ? that doesnt seem to match your schema. It should be domSnapshot = [ domSnapshot, ]; as per schema

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Screenshot 2024-09-19 at 11 06 58 PM
This is correct. check schema

Copy link
Contributor

@ninadbstack ninadbstack Sep 20, 2024

Choose a reason for hiding this comment

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

Any specific reason to put width and domSnapshot separately ? shouldnt width be part of it ?

Especially considering you are defining it in schema separately but not passing it here on line 97 ? if its optional it would work with domSnapshot as well will keep connected items together

Comment on lines 239 to 240
if (discovery.captureResponsiveAssetsEnabled) { forceReload = true; }
yield page.goto(snapshot.url, { cookies, forceReload });
Copy link
Contributor

Choose a reason for hiding this comment

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

Optional

Suggested change
if (discovery.captureResponsiveAssetsEnabled) { forceReload = true; }
yield page.goto(snapshot.url, { cookies, forceReload });
yield page.goto(snapshot.url, { cookies, forceReload: discovery.captureResponsiveAssetsEnabled });

Copy link
Contributor

Choose a reason for hiding this comment

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

@chinmay-browserstack also account for the additional cookies which we are planning to capture via SDKs, how they are going to be passed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can pass cookies is same fashion as we currently do inside domSnapshot object. we will override this value

this.log.debug(`Navigate to: ${url}`, this.meta);

if (forceReload) {
this.log.debug('Navigating to blank page', this.meta);
await this.session.send('Page.navigate', { url: 'about:blank' });
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we not need to wait for navigation here ? does it work regardless ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

about:blank is an empty page and does not load any external resources so i don't think we need to wait for it to load. it is instantaneous

Copy link
Contributor

Choose a reason for hiding this comment

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

have we added tests for this ? or ^ is from chromium documentation ?

@@ -291,6 +295,7 @@ export const snapshotSchema = {
domTransformation: { $ref: '/config/snapshot#/properties/domTransformation' },
enableLayout: { $ref: '/config/snapshot#/properties/enableLayout' },
sync: { $ref: '/config/snapshot#/properties/sync' },
multiDOM: { $ref: '/config/snapshot#/properties/multiDOM' },
Copy link
Contributor

Choose a reason for hiding this comment

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

is multiDOM confirmed?

Copy link
Contributor

Choose a reason for hiding this comment

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

Doesnt sound very straightforward for end user. captureMultipleWidths seems better - it does exactly what it says.

Comment on lines +228 to +233
return page.resize({
height: snapshot.minHeight,
deviceScaleFactor,
mobile,
width
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Generally if we are having too many CDP commands shouldn't we consider creating a wrapper class which will receive parameters and do the things using that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually page class is a wrapper only for running different cdp commands on browser.

@@ -365,8 +400,15 @@ export function createDiscoveryQueue(percy) {
disableCache: snapshot.discovery.disableCache,
allowedHostnames: snapshot.discovery.allowedHostnames,
disallowedHostnames: snapshot.discovery.disallowedHostnames,
getResource: u => snapshot.resources.get(u) || cache.get(u),
saveResource: r => { snapshot.resources.set(r.url, r); if (!r.root) { cache.set(r.url, r); } }
getResource: (u, width = null) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this responsible for returning the resource for that width?
If width is not present what are we planning to do, I am seeing we are returning first index are we sure its works?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it works. since only root resource is an array and in case if multiDOM is disabled we are storing root resource as a array only with no widths. that case is working fine. for other resources no change in logic

@@ -354,7 +354,7 @@ async function sendResponseResource(network, request, session) {
let send = (method, params) => network.send(session, method, params);

try {
let resource = network.intercept.getResource(url);
let resource = network.intercept.getResource(url, network.currentWidth);
Copy link
Contributor

Choose a reason for hiding this comment

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

apart from network.currentWidth is there any way to get any width this looks little weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can use cdp to get current window width but that will be slower operation as compared to this.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have commented to make it better

width
});
let resizePage = width => {
page.network.currentWidth = width;
Copy link
Contributor

Choose a reason for hiding this comment

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

Network is not directly related to current width. Dont update in network. Update in intercept instead as intercept needs current width to save/retrieve resources. Network just passes it to intercept in the end

@@ -62,6 +62,12 @@ export function createPercyServer(percy, port) {
build: percy.testing?.build ?? percy.build,
loglevel: percy.loglevel(),
config: percy.config,
widths: {
// This is always needed even if width is passed
mobile: percy.deviceDetails ? percy.deviceDetails.map((d) => d.width) : [],
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldnt we send dpr as well ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

doesn't make sense as we are just resizing page and not reloading page so changing dpr wouldn't help

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

Successfully merging this pull request may close these issues.

3 participants