WIP: Dodaj wsparcie dla Dockera #128
16
.dockerignore
Normal file
16
.dockerignore
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.log
|
||||||
|
node_modules
|
||||||
|
sidebar.js
|
||||||
|
web-ext-artifacts/
|
||||||
|
lib/*
|
||||||
|
yarn-error.log
|
||||||
|
rentgen.zip
|
||||||
|
|
||||||
|
# Generated PNG icons (build artifacts)
|
||||||
|
assets/icons/*.png
|
||||||
|
assets/icon-addon-*.png
|
||||||
|
|
||||||
|
# Exception: do not ignore the `browser-api` directory inside `lib`
|
||||||
|
!/lib/browser-api/
|
||||||
|
|
||||||
|
Dockerfile
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
sidebar.js
|
sidebar.js
|
||||||
/web-ext-artifacts/
|
/web-ext-artifacts/
|
||||||
|
/artifacts/
|
||||||
lib/*
|
lib/*
|
||||||
/yarn-error.log
|
/yarn-error.log
|
||||||
/rentgen.zip
|
/rentgen.zip
|
||||||
@ -11,4 +12,6 @@ lib/*
|
|||||||
/assets/icon-addon-*.png
|
/assets/icon-addon-*.png
|
||||||
|
|
||||||
# Exception: do not ignore the `browser-api` directory inside `lib`
|
# Exception: do not ignore the `browser-api` directory inside `lib`
|
||||||
!/lib/browser-api/
|
!/lib/browser-api/
|
||||||
|
|
||||||
|
.claude
|
||||||
|
|||||||
106
Dockerfile
Normal file
106
Dockerfile
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# Rentgen Browser Extension - Docker Build
|
||||||
|
# See README.md for detailed usage instructions
|
||||||
|
|
||||||
|
# Build stage
|
||||||
|
FROM node:lts AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files for dependency installation (better layer caching)
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# FIXME: COPY . . invalidates cache, so we need to optionally install Firefox
|
||||||
|
# and jump back to the correct stage. It might be too complex though, so we
|
||||||
|
# either need to use build args (if cache properly) or heavily document the
|
||||||
|
# stage transitions, maybe even with a graph.
|
||||||
|
|
||||||
|
# Copy source code (respecting .dockerignore)
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the extension for Firefox (default) - without tests
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Create the package
|
||||||
|
RUN npm run create-package
|
||||||
|
|
||||||
|
# Test builder stage - builds with ENABLE_TESTS=true
|
||||||
|
FROM node:lts AS test_builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package files for dependency installation
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build with tests enabled
|
||||||
|
RUN ENABLE_TESTS=true npm run build
|
||||||
|
|
||||||
|
# Create the package
|
||||||
|
RUN npm run create-package
|
||||||
|
|
||||||
|
# Code quality stage - for running quality checks
|
||||||
|
FROM builder AS code_quality
|
||||||
|
COPY tests/run-checks.sh /app/tests/run-checks.sh
|
||||||
|
RUN chmod +x /app/tests/run-checks.sh && /app/tests/run-checks.sh
|
||||||
|
|
||||||
|
# Artifacts stage - only contains the built artifacts (for --output)
|
||||||
|
FROM scratch AS artifacts
|
||||||
|
|
||||||
|
# Copy only the built extension zip file to root
|
||||||
|
COPY --from=builder /app/web-ext-artifacts/*.zip /
|
||||||
|
|
||||||
|
# Default stage - full development environment
|
||||||
|
FROM builder
|
||||||
|
|
||||||
|
# Default command shows the built artifact
|
||||||
|
CMD ["ls", "-lh", "/app/web-ext-artifacts/"]
|
||||||
|
|
||||||
|
# Runtime stage - for running extension with Selenium WebDriver
|
||||||
|
FROM node:lts AS runtime
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy built extension from test_builder (includes test code)
|
||||||
|
COPY --from=test_builder /app /app
|
||||||
|
|
||||||
|
# Install Firefox and Xvfb for headless execution
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
firefox-esr \
|
||||||
|
xvfb \
|
||||||
|
wget \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install geckodriver for WebDriver protocol
|
||||||
|
RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v0.34.0/geckodriver-v0.34.0-linux64.tar.gz \
|
||||||
|
&& tar -xzf geckodriver-v0.34.0-linux64.tar.gz \
|
||||||
|
&& mv geckodriver /usr/local/bin/ \
|
||||||
|
&& rm geckodriver-v0.34.0-linux64.tar.gz \
|
||||||
|
&& chmod +x /usr/local/bin/geckodriver
|
||||||
|
|
||||||
|
# Install Node.js test dependencies
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Set display for Xvfb
|
||||||
|
ENV DISPLAY=:99
|
||||||
|
|
||||||
|
# Start script (not used in verify stage)
|
||||||
|
CMD ["echo", "Use verify stage for testing"]
|
||||||
|
|
||||||
|
# Integration test stage - automated testing with exit code
|
||||||
|
FROM runtime AS integration_test
|
||||||
|
|
||||||
|
# Copy verification scripts
|
||||||
|
COPY tests/test_verify.mjs /app/tests/test_verify.mjs
|
||||||
|
COPY tests/test-lib.js /app/tests/test-lib.js
|
||||||
|
RUN chmod +x /app/tests/test_verify.mjs
|
||||||
|
|
||||||
|
# Run verification and exit with proper exit code
|
||||||
|
CMD ["node", "/app/tests/test_verify.mjs"]
|
||||||
29
README.md
29
README.md
@ -21,9 +21,21 @@ Firefox: https://addons.mozilla.org/en-US/firefox/addon/rentgen/
|
|||||||
### Pre-requirements
|
### Pre-requirements
|
||||||
|
|
||||||
- OS: Linux x86_64
|
- OS: Linux x86_64
|
||||||
- Node.js: 16.x version
|
- Node.js: 25.x version (recommended: use [fnm](https://github.com/Schniz/fnm) for automatic version management)
|
||||||
- npm: 7.x version or higher
|
- npm: 7.x version or higher
|
||||||
|
|
||||||
|
**Using fnm (recommended):**
|
||||||
|
|
||||||
|
If you're using fnm, it will automatically use the correct Node.js version specified in `.nvmrc`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install fnm (if not already installed)
|
||||||
|
curl -fsSL https://fnm.vercel.app/install | bash
|
||||||
|
|
||||||
|
# In the project directory, fnm will automatically use Node.js 25
|
||||||
|
fnm use
|
||||||
|
```
|
||||||
|
|
||||||
### Build steps
|
### Build steps
|
||||||
|
|
||||||
1. Pull repository or download a zip package
|
1. Pull repository or download a zip package
|
||||||
@ -82,9 +94,21 @@ Firefox: https://addons.mozilla.org/pl/firefox/addon/rentgen/
|
|||||||
### Wymagania wstępne
|
### Wymagania wstępne
|
||||||
|
|
||||||
- System operacyjny: Linux x86_64
|
- System operacyjny: Linux x86_64
|
||||||
- Node.js: 16.x
|
- Node.js: 25.x (zalecane: użyj [fnm](https://github.com/Schniz/fnm) do automatycznego zarządzania wersją)
|
||||||
- npm: 7.x lub wyższy
|
- npm: 7.x lub wyższy
|
||||||
|
|
||||||
|
**Używanie fnm (zalecane):**
|
||||||
|
|
||||||
|
Jeśli używasz fnm, automatycznie użyje prawidłowej wersji Node.js określonej w `.nvmrc`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Zainstaluj fnm (jeśli nie jest zainstalowane)
|
||||||
|
curl -fsSL https://fnm.vercel.app/install | bash
|
||||||
|
|
||||||
|
# W katalogu projektu fnm automatycznie użyje Node.js 25
|
||||||
|
fnm use
|
||||||
|
```
|
||||||
|
|
||||||
### Proces budowy
|
### Proces budowy
|
||||||
|
|
||||||
1. Pobierz repozytorium przez `git pull https://git.internet-czas-dzialac.pl/icd/rentgen.git` lub pobierz archwium zip
|
1. Pobierz repozytorium przez `git pull https://git.internet-czas-dzialac.pl/icd/rentgen.git` lub pobierz archwium zip
|
||||||
@ -112,3 +136,4 @@ Każdy problem zostanie sprawdzony i przeniesiony na wewnętrzną listę problem
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Test pre-commit hook - without Docker check
|
||||||
|
|||||||
@ -1,3 +1,35 @@
|
|||||||
import { init } from "./memory";
|
import { init, getMemory } from "./memory";
|
||||||
|
|
||||||
|
// Use global browser object directly (available in extension context)
|
||||||
|
declare const browser: any;
|
||||||
|
declare const ENABLE_TESTS: boolean;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
// Test verification handler for Marionette tests
|
||||||
|
// Tests real Rentgen functionality: counting third-party domains
|
||||||
|
if (ENABLE_TESTS) {
|
||||||
|
browser.runtime.onMessage.addListener((message: any, sender: any, sendResponse: any) => {
|
||||||
|
if (message.type === 'RENTGEN_TEST_VERIFICATION') {
|
||||||
|
// Get the origin from message (sent by content script)
|
||||||
|
const origin = message.origin;
|
||||||
|
|
||||||
|
// Access the memory to get clusters for this origin
|
||||||
|
const memory = getMemory();
|
||||||
|
const clusters = memory.getClustersForOrigin(origin);
|
||||||
|
const badgeCount = Object.keys(clusters).length;
|
||||||
|
|
||||||
|
// Send back the badge count (number of third-party domains)
|
||||||
|
const response = {
|
||||||
|
success: true,
|
||||||
|
badgeCount: badgeCount,
|
||||||
|
origin: origin,
|
||||||
|
clusterIds: Object.keys(clusters),
|
||||||
|
backgroundTimestamp: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
sendResponse(response);
|
||||||
|
return true; // Keep channel open for async response
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import verbs, { v } from './verbs';
|
|||||||
export default function useSurvey(
|
export default function useSurvey(
|
||||||
clusters: RequestCluster[],
|
clusters: RequestCluster[],
|
||||||
{ onComplete }: { onComplete: (sender: { data: RawAnswers }) => void }
|
{ onComplete }: { onComplete: (sender: { data: RawAnswers }) => void }
|
||||||
): Survey.ReactSurveyModel | null {
|
): Survey.Model | null {
|
||||||
const [survey, setSurvey] = React.useState<Survey.Model | null>(null);
|
const [survey, setSurvey] = React.useState<Survey.Model | null>(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const model = generateSurveyQuestions(clusters);
|
const model = generateSurveyQuestions(clusters);
|
||||||
|
|||||||
@ -43,7 +43,6 @@ export function StolenData({
|
|||||||
origin={origin}
|
origin={origin}
|
||||||
shorthost={cluster.id}
|
shorthost={cluster.id}
|
||||||
key={cluster.id + origin}
|
key={cluster.id + origin}
|
||||||
refreshToken={eventCounts[cluster.id] || 0}
|
|
||||||
minValueLength={minValueLength}
|
minValueLength={minValueLength}
|
||||||
cookiesOnly={cookiesOnly}
|
cookiesOnly={cookiesOnly}
|
||||||
cookiesOrOriginOnly={cookiesOrOriginOnly}
|
cookiesOrOriginOnly={cookiesOrOriginOnly}
|
||||||
|
|||||||
21
compose.yml
Normal file
21
compose.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
services:
|
||||||
|
rentgen_build:
|
||||||
|
build: .
|
||||||
|
|
||||||
|
rentgen_check:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: code_quality
|
||||||
|
|
||||||
|
rentgen_run:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: runtime
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
|
||||||
|
rentgen_verify:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: integration_test
|
||||||
|
restart: "no"
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import esbuild from 'esbuild';
|
import esbuild from 'esbuild';
|
||||||
import scss from 'esbuild-plugin-sass';
|
import scss from 'esbuild-plugin-sass';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
const watch = process.argv.includes('--watch') && {
|
const watch = process.argv.includes('--watch') && {
|
||||||
onRebuild(error) {
|
onRebuild(error) {
|
||||||
@ -8,6 +10,8 @@ const watch = process.argv.includes('--watch') && {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ENABLE_TESTS = process.env.ENABLE_TESTS === 'true';
|
||||||
|
|
||||||
// see https://github.com/evanw/esbuild/issues/806#issuecomment-779138268
|
// see https://github.com/evanw/esbuild/issues/806#issuecomment-779138268
|
||||||
let skipReactImports = {
|
let skipReactImports = {
|
||||||
name: 'skipReactImports',
|
name: 'skipReactImports',
|
||||||
@ -41,17 +45,23 @@ let skipReactImports = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const entryPoints = [
|
||||||
|
'components/toolbar/toolbar.tsx',
|
||||||
|
'components/sidebar/sidebar.tsx',
|
||||||
|
'components/report-window/report-window.tsx',
|
||||||
|
'background.ts',
|
||||||
|
'diag.tsx',
|
||||||
|
'styles/global.scss',
|
||||||
|
'styles/fonts.scss',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (ENABLE_TESTS) {
|
||||||
|
entryPoints.push('tests/inner-test-content-script.js');
|
||||||
|
}
|
||||||
|
|
||||||
esbuild
|
esbuild
|
||||||
.build({
|
.build({
|
||||||
entryPoints: [
|
entryPoints,
|
||||||
'components/toolbar/toolbar.tsx',
|
|
||||||
'components/sidebar/sidebar.tsx',
|
|
||||||
'components/report-window/report-window.tsx',
|
|
||||||
'background.ts',
|
|
||||||
'diag.tsx',
|
|
||||||
'styles/global.scss',
|
|
||||||
'styles/fonts.scss',
|
|
||||||
],
|
|
||||||
bundle: true,
|
bundle: true,
|
||||||
// minify: true,
|
// minify: true,
|
||||||
outdir: './lib',
|
outdir: './lib',
|
||||||
@ -60,9 +70,39 @@ esbuild
|
|||||||
define: {
|
define: {
|
||||||
PLUGIN_NAME: '"Rentgen"',
|
PLUGIN_NAME: '"Rentgen"',
|
||||||
PLUGIN_URL: '"https://addons.mozilla.org/pl/firefox/addon/rentgen/"',
|
PLUGIN_URL: '"https://addons.mozilla.org/pl/firefox/addon/rentgen/"',
|
||||||
|
ENABLE_TESTS: String(ENABLE_TESTS),
|
||||||
},
|
},
|
||||||
external: ['react', 'react-dom', 'survey-react'],
|
external: ['react', 'react-dom', 'survey-react'],
|
||||||
watch,
|
watch,
|
||||||
})
|
})
|
||||||
.then(() => console.log('Add-on was built'))
|
.then(() => {
|
||||||
|
console.log('Add-on was built');
|
||||||
|
|
||||||
|
// Modify manifest.json to include test content script when ENABLE_TESTS=true
|
||||||
|
if (ENABLE_TESTS) {
|
||||||
|
const manifestPath = path.join(process.cwd(), 'manifest.json');
|
||||||
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
||||||
|
|
||||||
|
// Add content_scripts for testing
|
||||||
|
if (!manifest.content_scripts) {
|
||||||
|
manifest.content_scripts = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if test script is already added
|
||||||
|
const hasTestScript = manifest.content_scripts.some(
|
||||||
|
cs => cs.js && cs.js.includes('lib/tests/inner-test-content-script.js')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasTestScript) {
|
||||||
|
manifest.content_scripts.push({
|
||||||
|
matches: ['<all_urls>'],
|
||||||
|
js: ['lib/tests/inner-test-content-script.js'],
|
||||||
|
run_at: 'document_start'
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 4));
|
||||||
|
console.log('Added test content script to manifest.json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(() => process.exit(1));
|
.catch(() => process.exit(1));
|
||||||
|
|||||||
@ -13,6 +13,7 @@ function setDomainsCount(counter: number, tabId: number) {
|
|||||||
|
|
||||||
export default class Memory extends SaferEmitter {
|
export default class Memory extends SaferEmitter {
|
||||||
origin_to_history = {} as Record<string, Record<string, RequestCluster>>;
|
origin_to_history = {} as Record<string, Record<string, RequestCluster>>;
|
||||||
|
|
||||||
async register(request: ExtendedRequest) {
|
async register(request: ExtendedRequest) {
|
||||||
await request.init();
|
await request.init();
|
||||||
if (!request.isThirdParty()) {
|
if (!request.isThirdParty()) {
|
||||||
@ -45,7 +46,6 @@ export default class Memory extends SaferEmitter {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
browser.webRequest.onBeforeRequest.addListener(
|
browser.webRequest.onBeforeRequest.addListener(
|
||||||
async (request) => {
|
async (request) => {
|
||||||
new ExtendedRequest(request);
|
new ExtendedRequest(request);
|
||||||
|
|||||||
126
package-lock.json
generated
126
package-lock.json
generated
@ -25,9 +25,13 @@
|
|||||||
"addons-linter": "^4.7.0",
|
"addons-linter": "^4.7.0",
|
||||||
"esbuild": "^0.14.14",
|
"esbuild": "^0.14.14",
|
||||||
"esbuild-plugin-sass": "^1.0.1",
|
"esbuild-plugin-sass": "^1.0.1",
|
||||||
|
"selenium-webdriver": "^4.38.0",
|
||||||
"typescript": "^4.6.4",
|
"typescript": "^4.6.4",
|
||||||
"web-ext": "^6.7.0",
|
"web-ext": "^6.7.0",
|
||||||
"web-ext-types": "^3.2.1"
|
"web-ext-types": "^3.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=25"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
@ -145,6 +149,13 @@
|
|||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@bazel/runfiles": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/@devicefarmer/adbkit": {
|
"node_modules/@devicefarmer/adbkit": {
|
||||||
"version": "2.11.3",
|
"version": "2.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-2.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-2.11.3.tgz",
|
||||||
@ -4130,9 +4141,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jszip": {
|
"node_modules/jszip": {
|
||||||
"version": "3.10.0",
|
"version": "3.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
|
||||||
"integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==",
|
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lie": "~3.3.0",
|
"lie": "~3.3.0",
|
||||||
@ -5838,6 +5849,64 @@
|
|||||||
"seek-table": "bin/seek-bzip-table"
|
"seek-table": "bin/seek-bzip-table"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/selenium-webdriver": {
|
||||||
|
"version": "4.38.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.38.0.tgz",
|
||||||
|
"integrity": "sha512-5/UXXFSQmn7FGQkbcpAqvfhzflUdMWtT7QqpEgkFD6Q6rDucxB5EUfzgjmr6JbUj30QodcW3mDXehzoeS/Vy5w==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/SeleniumHQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/selenium"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@bazel/runfiles": "^6.3.1",
|
||||||
|
"jszip": "^3.10.1",
|
||||||
|
"tmp": "^0.2.5",
|
||||||
|
"ws": "^8.18.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 20.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/selenium-webdriver/node_modules/tmp": {
|
||||||
|
"version": "0.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||||
|
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/selenium-webdriver/node_modules/ws": {
|
||||||
|
"version": "8.18.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
||||||
|
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.3.5",
|
"version": "7.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
@ -7377,9 +7446,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yargs-parser": {
|
"node_modules/yargs-parser": {
|
||||||
"version": "21.0.1",
|
"version": "21.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
"integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
@ -7506,6 +7575,12 @@
|
|||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@bazel/runfiles": {
|
||||||
|
"version": "6.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz",
|
||||||
|
"integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@devicefarmer/adbkit": {
|
"@devicefarmer/adbkit": {
|
||||||
"version": "2.11.3",
|
"version": "2.11.3",
|
||||||
"resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-2.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-2.11.3.tgz",
|
||||||
@ -10478,9 +10553,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jszip": {
|
"jszip": {
|
||||||
"version": "3.10.0",
|
"version": "3.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
|
||||||
"integrity": "sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==",
|
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lie": "~3.3.0",
|
"lie": "~3.3.0",
|
||||||
@ -11811,6 +11886,33 @@
|
|||||||
"commander": "^2.8.1"
|
"commander": "^2.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"selenium-webdriver": {
|
||||||
|
"version": "4.38.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.38.0.tgz",
|
||||||
|
"integrity": "sha512-5/UXXFSQmn7FGQkbcpAqvfhzflUdMWtT7QqpEgkFD6Q6rDucxB5EUfzgjmr6JbUj30QodcW3mDXehzoeS/Vy5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@bazel/runfiles": "^6.3.1",
|
||||||
|
"jszip": "^3.10.1",
|
||||||
|
"tmp": "^0.2.5",
|
||||||
|
"ws": "^8.18.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tmp": {
|
||||||
|
"version": "0.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||||
|
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "8.18.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
||||||
|
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "7.3.5",
|
"version": "7.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
@ -13049,9 +13151,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"yargs-parser": {
|
"yargs-parser": {
|
||||||
"version": "21.0.1",
|
"version": "21.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
"integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yauzl": {
|
"yauzl": {
|
||||||
|
|||||||
@ -19,7 +19,8 @@
|
|||||||
"create-package:firefox": "web-ext build --overwrite-dest --artifacts-dir ../web-ext-artifacts",
|
"create-package:firefox": "web-ext build --overwrite-dest --artifacts-dir ../web-ext-artifacts",
|
||||||
"create-package:chrome": "cd dist-chrome && 7z a -tzip ../web-ext-artifacts/rentgen-chrome-0.1.10.zip * && cd ..",
|
"create-package:chrome": "cd dist-chrome && 7z a -tzip ../web-ext-artifacts/rentgen-chrome-0.1.10.zip * && cd ..",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"lint": "web-ext lint"
|
"lint": "web-ext lint --ignore-files 'tests/**'",
|
||||||
|
"test": "ENABLE_TESTS=true npm run build && node tests/test_verify.mjs; git checkout manifest.json"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -28,6 +29,9 @@
|
|||||||
"homepage": "https://git.internet-czas-dzialac.pl/icd/rentgen",
|
"homepage": "https://git.internet-czas-dzialac.pl/icd/rentgen",
|
||||||
"author": "Kuba Orlik, Arkadiusz Wieczorek",
|
"author": "Kuba Orlik, Arkadiusz Wieczorek",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=25"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iabtcf/core": "^1.3.1",
|
"@iabtcf/core": "^1.3.1",
|
||||||
"@types/proposal-relative-indexing-method": "^0.1.0",
|
"@types/proposal-relative-indexing-method": "^0.1.0",
|
||||||
@ -57,6 +61,7 @@
|
|||||||
"addons-linter": "^4.7.0",
|
"addons-linter": "^4.7.0",
|
||||||
"esbuild": "^0.14.14",
|
"esbuild": "^0.14.14",
|
||||||
"esbuild-plugin-sass": "^1.0.1",
|
"esbuild-plugin-sass": "^1.0.1",
|
||||||
|
"selenium-webdriver": "^4.38.0",
|
||||||
"typescript": "^4.6.4",
|
"typescript": "^4.6.4",
|
||||||
"web-ext": "^6.7.0",
|
"web-ext": "^6.7.0",
|
||||||
"web-ext-types": "^3.2.1"
|
"web-ext-types": "^3.2.1"
|
||||||
|
|||||||
48
tests/inner-test-content-script.js
Normal file
48
tests/inner-test-content-script.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Test content script - RUNS INSIDE THE BROWSER EXTENSION
|
||||||
|
// Only loaded during automated testing (ENABLE_TESTS=true)
|
||||||
|
// This script proves bidirectional communication between content script and background
|
||||||
|
|
||||||
|
// Browser API polyfill for Chrome/Chromium compatibility
|
||||||
|
if (typeof browser === 'undefined') {
|
||||||
|
var browser = chrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial DOM marker to prove content script is injected
|
||||||
|
(function() {
|
||||||
|
function setMarker() {
|
||||||
|
if (document.body) {
|
||||||
|
document.body.setAttribute('data-rentgen-injected', 'true');
|
||||||
|
} else {
|
||||||
|
// Wait for DOM ready
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
document.body.setAttribute('data-rentgen-injected', 'true');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setMarker();
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Listen for test request from test script (test-lib.js)
|
||||||
|
document.addEventListener('DEBUG_rentgen_test_request', async (event) => {
|
||||||
|
try {
|
||||||
|
// Send message to background script to get badge count for this origin
|
||||||
|
// This tests real Rentgen functionality: counting third-party domains
|
||||||
|
const response = await browser.runtime.sendMessage({
|
||||||
|
type: 'RENTGEN_TEST_VERIFICATION',
|
||||||
|
origin: window.location.origin,
|
||||||
|
url: window.location.href,
|
||||||
|
title: document.title,
|
||||||
|
timestamp: event.detail?.timestamp || Date.now()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Store the badge count in DOM for the test script to read
|
||||||
|
if (response && response.success) {
|
||||||
|
document.body.setAttribute('data-rentgen-badge-count', String(response.badgeCount));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// If there's an error, the test will timeout waiting for badge count
|
||||||
|
console.error('Test verification error:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
21
tests/pre-commit
Executable file
21
tests/pre-commit
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Pre-commit hook for Rentgen extension
|
||||||
|
# Builds and runs verification tests before allowing commit
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Running pre-commit checks..."
|
||||||
|
|
||||||
|
# Build all stages
|
||||||
|
echo "Building Docker images..."
|
||||||
|
docker compose build
|
||||||
|
|
||||||
|
# Run code quality checks (typecheck + lint)
|
||||||
|
echo "Running code quality checks..."
|
||||||
|
docker compose up --abort-on-container-exit --exit-code-from rentgen_check rentgen_check
|
||||||
|
|
||||||
|
# Run integration tests
|
||||||
|
echo "Running integration tests..."
|
||||||
|
docker compose up --abort-on-container-exit --exit-code-from rentgen_verify rentgen_verify
|
||||||
|
|
||||||
|
echo "✓ All pre-commit checks passed!"
|
||||||
16
tests/run-checks.sh
Executable file
16
tests/run-checks.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Code quality checks for Rentgen extension
|
||||||
|
# Runs typecheck and lint
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Running type checking..."
|
||||||
|
npm run typecheck
|
||||||
|
|
||||||
|
echo "Running linter..."
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
echo "Running tests..."
|
||||||
|
npm run test
|
||||||
|
|
||||||
|
echo "✓ All code quality checks passed!"
|
||||||
55
tests/test-lib.js
Normal file
55
tests/test-lib.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Test library for Marionette-based extension verification
|
||||||
|
// This JavaScript code runs in the browser context via Marionette
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if test content script is loaded
|
||||||
|
* The content script is automatically injected by manifest.json when ENABLE_TESTS=true
|
||||||
|
* @returns {Promise<boolean>} - True if content script is loaded
|
||||||
|
*/
|
||||||
|
async function waitForTestContentScript() {
|
||||||
|
// Wait for content script to set the marker
|
||||||
|
let attempts = 0;
|
||||||
|
while (attempts < 50) {
|
||||||
|
if (document.body && document.body.getAttribute('data-rentgen-injected') === 'true') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that background script returns badge count correctly
|
||||||
|
* Tests real Rentgen functionality: counting third-party domains
|
||||||
|
* @returns {Promise<number|null>} - Badge count (number of third-party domains) or null on failure
|
||||||
|
*/
|
||||||
|
async function testBadgeCount() {
|
||||||
|
// Wait for content script to be loaded
|
||||||
|
const loaded = await waitForTestContentScript();
|
||||||
|
if (!loaded) {
|
||||||
|
return -1; // Content script not loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch test request to content script
|
||||||
|
document.dispatchEvent(new CustomEvent('DEBUG_rentgen_test_request', {
|
||||||
|
detail: { timestamp: Date.now() }
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Wait for background response with badge count
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
let attempts = 0;
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
attempts++;
|
||||||
|
const badgeCount = document.body.getAttribute('data-rentgen-badge-count');
|
||||||
|
|
||||||
|
if (badgeCount !== null) {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
resolve(parseInt(badgeCount));
|
||||||
|
} else if (attempts > 50) {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
140
tests/test_verify.mjs
Executable file
140
tests/test_verify.mjs
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* test_verify.mjs - Extension badge count verification test using Selenium WebDriver
|
||||||
|
*
|
||||||
|
* Verifies Rentgen's core functionality: counting third-party domains.
|
||||||
|
* Tests two scenarios:
|
||||||
|
* 1. Site without third-party domains (news.ycombinator.com) → badge = 0
|
||||||
|
* 2. Site with third-party domains (pudelek.pl) → badge > 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Builder } from 'selenium-webdriver';
|
||||||
|
import firefox from 'selenium-webdriver/firefox.js';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { dirname, join } from 'path';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
// Load test library once
|
||||||
|
const testLibPath = join(__dirname, 'test-lib.js');
|
||||||
|
const testLib = readFileSync(testLibPath, 'utf-8');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test badge count for a specific URL
|
||||||
|
* @param {WebDriver} driver - Selenium WebDriver instance
|
||||||
|
* @param {string} url - URL to test
|
||||||
|
* @param {number} waitMs - How long to wait after page load
|
||||||
|
* @returns {Promise<number|null>} Badge count or null on failure
|
||||||
|
*/
|
||||||
|
async function testUrl(driver, url, waitMs = 5000) {
|
||||||
|
await driver.get(url);
|
||||||
|
await driver.sleep(waitMs);
|
||||||
|
|
||||||
|
const badgeCount = await driver.executeAsyncScript(`
|
||||||
|
const testLibCode = arguments[0];
|
||||||
|
const callback = arguments[1];
|
||||||
|
|
||||||
|
eval(testLibCode);
|
||||||
|
testBadgeCount().then(callback).catch(err => callback(null));
|
||||||
|
`, testLib);
|
||||||
|
|
||||||
|
return badgeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify badge count matches expected value
|
||||||
|
* @param {number|null} actual - Actual badge count
|
||||||
|
* @param {number|string} expected - Expected value (number or '>0')
|
||||||
|
* @returns {boolean} Whether assertion passed
|
||||||
|
*/
|
||||||
|
function assertBadgeCount(actual, expected) {
|
||||||
|
if (actual === null) return false;
|
||||||
|
if (expected === '>0') return actual > 0;
|
||||||
|
return actual === expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testBadgeCount() {
|
||||||
|
let driver = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const extensionPath = join(__dirname, '..');
|
||||||
|
|
||||||
|
console.log(' Launching Firefox with extension...');
|
||||||
|
|
||||||
|
const options = new firefox.Options();
|
||||||
|
if (process.env.HEADLESS !== 'false') {
|
||||||
|
options.addArguments('-headless');
|
||||||
|
}
|
||||||
|
|
||||||
|
driver = await new Builder()
|
||||||
|
.forBrowser('firefox')
|
||||||
|
.setFirefoxOptions(options)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
console.log(' Installing extension...');
|
||||||
|
await driver.installAddon(extensionPath, true);
|
||||||
|
|
||||||
|
// Test cases: [url, expectedBadgeCount, waitMs, name]
|
||||||
|
const testCases = [
|
||||||
|
['https://news.ycombinator.com', 0, 5000, 'news.ycombinator.com'],
|
||||||
|
['https://pudelek.pl', '>0', 10000, 'pudelek.pl']
|
||||||
|
];
|
||||||
|
|
||||||
|
const results = {};
|
||||||
|
|
||||||
|
for (const [url, expected, waitMs, name] of testCases) {
|
||||||
|
console.log(` Testing ${name} (expected: ${expected === '>0' ? '>0' : expected} third-party domains)...`);
|
||||||
|
const badgeCount = await testUrl(driver, url, waitMs);
|
||||||
|
results[name] = badgeCount;
|
||||||
|
console.log(` → Badge count: ${badgeCount}`);
|
||||||
|
|
||||||
|
if (!assertBadgeCount(badgeCount, expected)) {
|
||||||
|
await driver.quit();
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: `${name}: expected ${expected}, got ${badgeCount}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await driver.quit();
|
||||||
|
return { success: true, results };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (driver) {
|
||||||
|
await driver.quit();
|
||||||
|
}
|
||||||
|
return { success: false, error: error.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
console.log('Starting Rentgen badge count verification test...');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const result = await testBadgeCount();
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
if (!result.success) {
|
||||||
|
console.log(`FAIL: ${result.error}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('PASS: Badge count test succeeded!');
|
||||||
|
const resultNames = Object.keys(result.results);
|
||||||
|
for (const name of resultNames) {
|
||||||
|
console.log(` - ${name}: ${result.results[name]} third-party domains`);
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle signals
|
||||||
|
process.on('SIGINT', () => process.exit(130));
|
||||||
|
process.on('SIGTERM', () => process.exit(143));
|
||||||
|
|
||||||
|
main().catch(error => {
|
||||||
|
console.error(`ERROR: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user