diff --git a/package.json b/package.json index bd4ef74..7b20fb8 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "jest": "^28.1.0", "nock": "^13.2.4", "np": "^8.0.4", - "pagexray": "^4.4.2", "prettier": "^2.6.2" }, "jest": { @@ -76,4 +75,4 @@ "type": "git", "url": "https://github.com/thegreenwebfoundation/co2.js.git" } -} +} \ No newline at end of file diff --git a/src/co2.js b/src/co2.js index 41a98da..7bddf6c 100644 --- a/src/co2.js +++ b/src/co2.js @@ -208,108 +208,6 @@ class CO2 { ); } } - - perDomain(pageXray, greenDomains) { - const co2PerDomain = []; - for (let domain of Object.keys(pageXray.domains)) { - let co2; - if (greenDomains && greenDomains.indexOf(domain) > -1) { - co2 = this.perByte(pageXray.domains[domain].transferSize, true); - } else { - co2 = this.perByte(pageXray.domains[domain].transferSize); - } - co2PerDomain.push({ - domain, - co2, - transferSize: pageXray.domains[domain].transferSize, - }); - } - co2PerDomain.sort((a, b) => b.co2 - a.co2); - - return co2PerDomain; - } - - perPage(pageXray, green) { - // Accept an xray object, and if we receive a boolean as the second - // argument, we assume every request we make is sent to a server - // running on renwewable power. - - // if we receive an array of domains, return a number accounting the - // reduced CO2 from green hosted domains - - const domainCO2 = this.perDomain(pageXray, green); - let totalCO2 = 0; - for (let domain of domainCO2) { - totalCO2 += domain.co2; - } - return totalCO2; - } - - perContentType(pageXray, greenDomains) { - const co2PerContentType = {}; - for (let asset of pageXray.assets) { - const domain = new URL(asset.url).domain; - const transferSize = asset.transferSize; - const co2ForTransfer = this.perByte( - transferSize, - greenDomains && greenDomains.indexOf(domain) > -1 - ); - const contentType = asset.type; - if (!co2PerContentType[contentType]) { - co2PerContentType[contentType] = { co2: 0, transferSize: 0 }; - } - co2PerContentType[contentType].co2 += co2ForTransfer; - co2PerContentType[contentType].transferSize += transferSize; - } - // restructure and sort - const all = []; - for (let type of Object.keys(co2PerContentType)) { - all.push({ - type, - co2: co2PerContentType[type].co2, - transferSize: co2PerContentType[type].transferSize, - }); - } - all.sort((a, b) => b.co2 - a.co2); - return all; - } - - dirtiestResources(pageXray, greenDomains) { - const allAssets = []; - for (let asset of pageXray.assets) { - const domain = new URL(asset.url).domain; - const transferSize = asset.transferSize; - const co2ForTransfer = this.perByte( - transferSize, - greenDomains && greenDomains.indexOf(domain) > -1 - ); - allAssets.push({ url: asset.url, co2: co2ForTransfer, transferSize }); - } - allAssets.sort((a, b) => b.co2 - a.co2); - - return allAssets.slice(0, allAssets.length > 10 ? 10 : allAssets.length); - } - - perParty(pageXray, greenDomains) { - let firstParty = 0; - let thirdParty = 0; - // calculate co2 per first/third party - const firstPartyRegEx = pageXray.firstPartyRegEx; - for (let d of Object.keys(pageXray.domains)) { - if (!d.match(firstPartyRegEx)) { - thirdParty += this.perByte( - pageXray.domains[d].transferSize, - greenDomains && greenDomains.indexOf(d) > -1 - ); - } else { - firstParty += this.perByte( - pageXray.domains[d].transferSize, - greenDomains && greenDomains.indexOf(d) > -1 - ); - } - } - return { firstParty, thirdParty }; - } } export { CO2 }; diff --git a/src/co2.test.js b/src/co2.test.js index cd616b6..72fb81e 100644 --- a/src/co2.test.js +++ b/src/co2.test.js @@ -1,10 +1,6 @@ "use strict"; -import fs from "fs"; -import path from "path"; -import { MILLION, ONEBYTE, SWD } from "./constants/test-constants.js"; - -import pagexray from "pagexray"; +import { MILLION, SWD } from "./constants/test-constants.js"; import CO2 from "./co2.js"; import { averageIntensity, marginalIntensity } from "./index.js"; @@ -12,143 +8,18 @@ import { averageIntensity, marginalIntensity } from "./index.js"; const TwnGridIntensityValue = averageIntensity.data["TWN"]; describe("co2", () => { - let har, co2; - describe("1 byte model", () => { - const { TGWF_GREY_VALUE, TGWF_GREEN_VALUE, TGWF_MIXED_VALUE } = ONEBYTE; - - beforeEach(() => { - co2 = new CO2({ model: "1byte" }); - har = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, "../data/fixtures/tgwf.har"), - "utf8" - ) - ); - }); - - describe("perPage", () => { - it("returns CO2 for total transfer for page", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - - expect(co2.perPage(pageXrayRun).toFixed(5)).toBe( - TGWF_GREY_VALUE.toFixed(5) - ); - }); - it("returns lower CO2 for page served from green site", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - let green = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - expect(co2.perPage(pageXrayRun, green)).toBeLessThan(TGWF_GREY_VALUE); - }); - it("returns a lower CO2 number where *some* domains use green power", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - // green can be true, or a array containing entries - let green = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - expect(co2.perPage(pageXrayRun, green).toFixed(5)).toBe( - TGWF_MIXED_VALUE.toFixed(5) - ); - }); - }); - describe("perDomain", () => { - it("shows object listing Co2 for each domain", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - const res = co2.perDomain(pageXrayRun); - - const domains = [ - "thegreenwebfoundation.org", - "www.thegreenwebfoundation.org", - "maxcdn.bootstrapcdn.com", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - - for (let obj of res) { - expect(domains.indexOf(obj.domain)).toBeGreaterThan(-1); - expect(typeof obj.co2).toBe("number"); - } - }); - it("shows lower Co2 for green domains", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - - const greenDomains = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - const res = co2.perDomain(pageXrayRun); - const resWithGreen = co2.perDomain(pageXrayRun, greenDomains); - - for (let obj of res) { - expect(typeof obj.co2).toBe("number"); - } - for (let obj of greenDomains) { - let index = 0; - expect(resWithGreen[index].co2).toBeLessThan(res[index].co2); - index++; - } - }); - }); - }); + let co2; describe("Sustainable Web Design model as simple option", () => { // the SWD model should have slightly higher values as // we include more of the system in calculations for the // same levels of data transfer - const { - MILLION_GREEN, - MILLION_GREY, - TGWF_GREY_VALUE, - TGWF_MIXED_VALUE, - MILLION_PERVISIT_GREY, - MILLION_PERVISIT_GREEN, - } = SWD; + const { MILLION_PERVISIT_GREY, MILLION_PERVISIT_GREEN } = SWD; // We're not passing in a model parameter here to check that SWD is used by default beforeEach(() => { co2 = new CO2(); - har = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, "../data/fixtures/tgwf.har"), - "utf8" - ) - ); }); describe("perVisit", () => { @@ -173,105 +44,6 @@ describe("co2", () => { }); }); - describe("perPage", () => { - it("returns CO2 for total transfer for page", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - - expect(parseFloat(co2.perPage(pageXrayRun).toFixed(5))).toBeCloseTo( - parseFloat(TGWF_GREY_VALUE.toFixed(5)), - 3 - ); - }); - it("returns lower CO2 for page served from green site", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - let green = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - expect(co2.perPage(pageXrayRun, green)).toBeLessThan(TGWF_GREY_VALUE); - }); - it("returns a lower CO2 number where *some* domains use green power", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - // green can be true, or a array containing entries - let green = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - expect( - parseFloat(co2.perPage(pageXrayRun, green).toFixed(5)) - ).toBeCloseTo(parseFloat(TGWF_MIXED_VALUE.toFixed(5)), 3); - }); - }); - describe("perDomain", () => { - it("shows object listing Co2 for each domain", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - const res = co2.perDomain(pageXrayRun); - - const domains = [ - "thegreenwebfoundation.org", - "www.thegreenwebfoundation.org", - "maxcdn.bootstrapcdn.com", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - - for (let obj of res) { - expect(domains.indexOf(obj.domain)).toBeGreaterThan(-1); - expect(typeof obj.co2).toBe("number"); - } - }); - it("shows lower Co2 for green domains", () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; - - const greenDomains = [ - "www.thegreenwebfoundation.org", - "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", - ]; - const res = co2.perDomain(pageXrayRun); - const resWithGreen = co2.perDomain(pageXrayRun, greenDomains); - - for (let obj of res) { - expect(typeof obj.co2).toBe("number"); - } - for (let obj of greenDomains) { - let index = 0; - expect(resWithGreen[index].co2).toBeLessThan(res[index].co2); - index++; - } - }); - }); describe("Returning results by segment", () => { const { MILLION_GREY, diff --git a/src/hosting-node.js b/src/hosting-node.js index 87eadfb..064e207 100644 --- a/src/hosting-node.js +++ b/src/hosting-node.js @@ -107,20 +107,8 @@ async function checkDomainsAgainstAPI(domains, userAgentIdentifier) { } } -/** - * Take the result of a pageXray and check the domains in it against the database. - * @param {object} pageXray - The result of a pageXray. - * @param {object} db - A database object to use for lookups. - * @returns {array} - An array indicating whether the domain is hosted by a green web host. - */ -async function checkPage(pageXray, db) { - const domains = Object.keys(pageXray.domains); - return check(domains, db); -} - export default { check, - checkPage, greendomains: hostingJSON.greenDomainsFromResults, loadJSON: hostingJSON.loadJSON, }; diff --git a/src/hosting.test.js b/src/hosting.test.js index 666eb83..235fc13 100644 --- a/src/hosting.test.js +++ b/src/hosting.test.js @@ -1,11 +1,8 @@ "use strict"; -import fs from "fs"; import https from "https"; import path from "path"; -import pagexray from "pagexray"; - import hosting from "./hosting-node.js"; jest.mock("https"); @@ -25,35 +22,21 @@ describe("hosting", () => { let har; let httpsGetSpy; beforeEach(() => { - har = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, "../data/fixtures/tgwf.har"), - "utf8" - ) - ); httpsGetSpy = jest.spyOn(https, "get"); jest.clearAllMocks(); }); describe("checking all domains on a page object with #checkPage", () => { it("returns a list of green domains, when passed a page object", async () => { - const pages = pagexray.convert(har); - const pageXrayRun = pages[0]; const db = await hosting.loadJSON(jsonPath); - const greenDomains = await hosting.checkPage(pageXrayRun, db); + const greenDomains = await hosting.check( + ["www.thegreenwebfoundation.org", "fonts.googleapis.com"], + db + ); - expect(greenDomains).toHaveLength(11); + expect(greenDomains).toHaveLength(2); const expectedGreendomains = [ - "maxcdn.bootstrapcdn.com", - "thegreenwebfoundation.org", "www.thegreenwebfoundation.org", "fonts.googleapis.com", - "ajax.googleapis.com", - "assets.digitalclimatestrike.net", - "cdnjs.cloudflare.com", - "graphite.thegreenwebfoundation.org", - "analytics.thegreenwebfoundation.org", - "fonts.gstatic.com", - "api.thegreenwebfoundation.org", ]; greenDomains.forEach((dom) => { expect(expectedGreendomains).toContain(dom);