diff --git a/src/lib/connectors/shared/remote-debugging-connector.ts b/src/lib/connectors/shared/remote-debugging-connector.ts index 994c6bcef25..f9557caef9f 100644 --- a/src/lib/connectors/shared/remote-debugging-connector.ts +++ b/src/lib/connectors/shared/remote-debugging-connector.ts @@ -326,7 +326,12 @@ export class Connector implements IConnector { }; } - if (hasAttributeWithValue(data.element, 'link', 'rel', 'icon')) { + const hasFaviconLinkTag = hasAttributeWithValue(data.element, 'link', 'rel', 'icon'); + // If favicon is not present in the html, CDP will send a request to get favicon from the root directory. + // We should set the tag to true in this case to avoid fetching favicon twice. + const hasFaviconInRootDir = data.request.url.endsWith('/favicon.ico'); + + if (hasFaviconLinkTag || hasFaviconInRootDir) { this._faviconLoaded = true; } @@ -487,8 +492,12 @@ export class Connector implements IConnector { * * uses the `src` attribute of `` if present. * * uses `favicon.ico` and the final url after redirects. */ - private async getFavicon(element?: AsyncHTMLElement) { - const href = element ? element.getAttribute('href') : '/favicon.ico'; + private async getFavicon(element: AsyncHTMLElement) { + const href = element.getAttribute('href'); + + if (!href) { // `href` is empty. + return; + } try { debug(`resource ${href} to be fetched`); @@ -545,7 +554,14 @@ export class Connector implements IConnector { } if (!this._faviconLoaded) { - await this.getFavicon((await this._dom.querySelectorAll('link[rel~="icon"]'))[0]); + // We don't need to consider fetching favicon from the root here. + // It should never get to this point if favicon is in the root directory. + const faviconElement = (await this._dom.querySelectorAll('link[rel~="icon"]'))[0]; + + if (faviconElement) { + await this.getFavicon(faviconElement); + } + } await this._server.emitAsync('scan::end', event);