UNPKG

@realfavicongenerator/check-favicon

Version:

Check the favicon of a website

267 lines (266 loc) 11.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const node_html_parser_1 = require("node-html-parser"); const desktop_1 = require("./desktop"); const types_1 = require("../types"); const helper_1 = require("../helper"); const test_helper_1 = require("../test-helper"); const runSvgTest = (headFragment_1, output_1, ...args_1) => __awaiter(void 0, [headFragment_1, output_1, ...args_1], void 0, function* (headFragment, output, fetchDatabase = {}) { const root = headFragment ? (0, node_html_parser_1.parse)(headFragment) : null; const result = yield (0, desktop_1.checkSvgFavicon)('https://example.com/', root, (0, test_helper_1.testFetcher)(fetchDatabase)); const filteredMessages = result.messages.map(m => ({ status: m.status, id: m.id })); expect(filteredMessages).toEqual(output.messages); }); test('checkSvgFavicon - noHead', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(null, { messages: [{ status: types_1.CheckerStatus.Error, id: types_1.MessageId.noHead, }], icons: { png: null, ico: null, svg: null, } }); })); test('checkSvgFavicon - noSvgFavicon', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(`<title>Some text</title>`, { messages: [{ status: types_1.CheckerStatus.Error, id: types_1.MessageId.noSvgFavicon, }], icons: { png: null, ico: null, svg: null, } }); })); test('checkSvgFavicon - multipleSvgFavicons', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(` <link rel="icon" type="image/svg+xml" href="/the-icon.svg" /> <link rel="icon" type="image/svg+xml" href="/another-icon.svg" /> `, { messages: [{ status: types_1.CheckerStatus.Error, id: types_1.MessageId.multipleSvgFavicons, }], icons: { png: null, ico: null, svg: null, } }); })); test('checkSvgFavicon - svgFaviconDeclared & noSvgFaviconHref', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(`<link rel="icon" type="image/svg+xml" />`, { messages: [{ status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDeclared, }, { status: types_1.CheckerStatus.Error, id: types_1.MessageId.noSvgFaviconHref, }], icons: { png: null, ico: null, svg: null, } }); })); test('checkSvgFavicon - svgFaviconDeclared & svgFavicon404', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(`<link rel="icon" type="image/svg+xml" href="/the-icon.svg" />`, { messages: [{ status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDeclared, }, { status: types_1.CheckerStatus.Error, id: types_1.MessageId.svgFavicon404, }], icons: { png: null, ico: null, svg: { content: null, url: 'https://example.com/the-icon.svg', width: null, height: null, }, } }); })); test('checkSvgFavicon - svgFaviconDeclared & svgFaviconCannotGet', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(`<link rel="icon" type="image/svg+xml" href="/the-icon.svg" />`, { messages: [{ status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDeclared, }, { status: types_1.CheckerStatus.Error, id: types_1.MessageId.svgFaviconCannotGet, }], icons: { png: null, ico: null, svg: { content: null, url: 'https://example.com/the-icon.svg', width: null, height: null, }, } }, { 'https://example.com/the-icon.svg': { status: 403, contentType: 'image/svg+xml' } }); })); // For https://github.com/RealFaviconGenerator/core/issues/2 test('checkSvgFavicon - Protocol-relative URL', () => __awaiter(void 0, void 0, void 0, function* () { yield runSvgTest(`<link rel="icon" type="image/svg+xml" href="//example.com/the-icon.svg" />`, { messages: [{ status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDeclared, }, { status: types_1.CheckerStatus.Error, id: types_1.MessageId.svgFaviconCannotGet, }], icons: { png: null, ico: null, svg: { content: null, url: 'https://example.com/the-icon.svg', width: null, height: null, }, } }, { 'https://example.com/the-icon.svg': { status: 403, contentType: 'image/svg+xml' } }); })); test('checkSvgFavicon - svgFaviconDeclared & svgFaviconDownloadable & svgFaviconSquare', () => __awaiter(void 0, void 0, void 0, function* () { const testIconPath = './fixtures/happy-face.svg'; const serpIcon = yield (0, helper_1.filePathToString)(testIconPath); yield runSvgTest(`<link rel="icon" type="image/svg+xml" href="/the-icon.svg" />`, { messages: [ { status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDeclared, }, { status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconDownloadable, }, { status: types_1.CheckerStatus.Ok, id: types_1.MessageId.svgFaviconSquare, } ], icons: { png: null, ico: null, svg: { content: yield (0, helper_1.filePathToDataUrl)(testIconPath), url: 'https://example.com/the-icon.svg', width: 36, height: 36, }, } }, { 'https://example.com/the-icon.svg': { status: 200, contentType: 'image/svg+xml', readableStream: yield (0, helper_1.filePathToReadableStream)(testIconPath) } }); })); const runPngTest = (headFragment_1, output_1, ...args_1) => __awaiter(void 0, [headFragment_1, output_1, ...args_1], void 0, function* (headFragment, output, fetchDatabase = {}) { const root = headFragment ? (0, node_html_parser_1.parse)(headFragment) : null; const result = yield (0, desktop_1.checkPngFavicon)('https://example.com/', root, (0, test_helper_1.testFetcher)(fetchDatabase)); const filteredMessages = result.messages.map(m => ({ status: m.status, id: m.id })); expect(filteredMessages).toEqual(output.messages); }); const testIcon16 = './fixtures/16x16.png'; const testIcon32 = './fixtures/32x32.png'; const testIcon48 = './fixtures/48x48.png'; const testIcon96 = './fixtures/96x96.png'; test('checkSvgFavicon - Three PNG icons with different sizes', () => __awaiter(void 0, void 0, void 0, function* () { yield runPngTest(` <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="48x48" href="/favicon/favicon-48x48.png"> <link rel="icon" type="image/png" sizes="96x96" href="/favicon/favicon-96x96.png"> `, { messages: [{ status: types_1.CheckerStatus.Ok, id: types_1.MessageId.desktopPngFaviconDeclared, }, { status: types_1.CheckerStatus.Ok, id: types_1.MessageId.desktopPngFaviconDownloadable, }, { status: types_1.CheckerStatus.Ok, id: types_1.MessageId.desktopPngFaviconRightSize, }], icons: { png: { content: yield (0, helper_1.filePathToDataUrl)(testIcon96), url: 'https://example.com/favicon/favicon-96x96.png', width: 96, height: 96, }, ico: null, svg: null, } }, { 'https://example.com/favicon/favicon-16x16.png': { status: 200, contentType: 'image/png', readableStream: yield (0, helper_1.filePathToReadableStream)(testIcon16), }, 'https://example.com/favicon/favicon-32x32.png': { status: 200, contentType: 'image/png', readableStream: yield (0, helper_1.filePathToReadableStream)(testIcon32), }, 'https://example.com/favicon/favicon-48x48.png': { status: 200, contentType: 'image/png', readableStream: yield (0, helper_1.filePathToReadableStream)(testIcon48), }, 'https://example.com/favicon/favicon-96x96.png': { status: 200, contentType: 'image/png', readableStream: yield (0, helper_1.filePathToReadableStream)(testIcon96), } }); })); // When only an ICO favicon is available (no PNG, no SVG), the top-level // `icon` field of the DesktopFaviconReport must fall back to the ICO content // instead of being null. test('checkDesktopFavicon - ICO content is used as top-level icon when no PNG/SVG', () => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; const testIconPath = './fixtures/simple-ico.ico'; const root = (0, node_html_parser_1.parse)(`<link rel="shortcut icon" href="/favicon.ico" />`); const result = yield (0, desktop_1.checkDesktopFavicon)('https://example.com/', root, (0, test_helper_1.testFetcher)({ 'https://example.com/favicon.ico': { status: 200, contentType: 'image/x-icon', readableStream: yield (0, helper_1.filePathToReadableStream)(testIconPath), }, })); expect(result.icons.png).toEqual({ content: null, url: null, width: null, height: null }); expect(result.icons.svg).toEqual({ content: null, url: null, width: null, height: null }); expect((_a = result.icons.ico) === null || _a === void 0 ? void 0 : _a.content).not.toBeNull(); expect(result.icon).not.toBeNull(); expect(result.icon).toMatch(/^data:image\/(png|bmp);base64,/); expect(result.icon).toEqual((_b = result.icons.ico) === null || _b === void 0 ? void 0 : _b.content); }));