import re

from dataclasses import dataclass, field
from swesmith.constants import ENV_NAME, KEY_PATCH
from swebench.harness.constants import TestStatus
from swesmith.profiles.base import RepoProfile, registry
from swesmith.profiles.utils import X11_DEPS
from unidiff import PatchSet


@dataclass
class JavaScriptProfile(RepoProfile):
    """
    Profile for JavaScript repositories.
    """

    exts: list[str] = field(default_factory=lambda: [".js"])

    def extract_entities(
        self,
        dirs_exclude: list[str] = None,
        dirs_include: list[str] = [],
        exclude_tests: bool = True,
        max_entities: int = -1,
    ) -> list:
        """
        Override to exclude JavaScript build artifacts by default.

        JavaScript projects often have build/dist directories that contain
        transpiled/bundled code. We should only analyze source files.
        """
        if dirs_exclude is None:
            # Default exclusions for JavaScript projects
            dirs_exclude = [
                "dist",
                "build",
                "node_modules",
                "coverage",
                ".next",
                "out",
                "examples",
                "docs",
                "bin",
            ]

        return super().extract_entities(
            dirs_exclude=dirs_exclude,
            dirs_include=dirs_include,
            exclude_tests=exclude_tests,
            max_entities=max_entities,
        )


def default_npm_install_dockerfile(mirror_name: str, node_version: str = "18") -> str:
    return f"""FROM node:{node_version}-bullseye
RUN apt update && apt install -y git  
RUN git clone https://github.com/{mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
"""


def parse_log_jest(log: str) -> dict[str, str]:
    """
    Parser for test logs generated with Jest. Assumes --verbose flag.

    Args:
        log (str): log content
    Returns:
        dict: test case to test status mapping
    """
    test_status_map = {}

    pattern = r"^\s*(✓|✕|○)\s(.+?)(?:\s\((\d+\s*m?s)\))?$"

    for line in log.split("\n"):
        match = re.match(pattern, line.strip())
        if match:
            status_symbol, test_name, _duration = match.groups()
            if status_symbol == "✓":
                test_status_map[test_name] = TestStatus.PASSED.value
            elif status_symbol == "✕":
                test_status_map[test_name] = TestStatus.FAILED.value
            elif status_symbol == "○":
                test_status_map[test_name] = TestStatus.SKIPPED.value
    return test_status_map


def parse_log_mocha(log: str) -> dict[str, str]:
    test_status_map = {}
    # Pattern for checkmark/x/dash style output
    # Note: Match both ✓ (U+2713) and ✔ (U+2714) checkmarks as different Mocha versions use different symbols
    pattern = r"^\s*([✓✔]|✖|-)\s(.+?)(?:\s\((\d+\s*m?s)\))?$"
    # Pattern for numbered failures like "1) test name" or "1) should solve..."
    fail_pattern = r"^\s*\d+\)\s+(.+?)(?:\s\((\d+\s*m?s)\))?$"
    for line in log.split("\n"):
        match = re.match(pattern, line.strip())
        if match:
            status_symbol, test_name, _duration = match.groups()
            if status_symbol in ("✓", "✔"):
                test_status_map[test_name] = TestStatus.PASSED.value
            elif status_symbol == "✖":
                test_status_map[test_name] = TestStatus.FAILED.value
            elif status_symbol == "-":
                test_status_map[test_name] = TestStatus.SKIPPED.value
        else:
            # Try numbered failure pattern
            fail_match = re.match(fail_pattern, line.strip())
            if fail_match:
                test_name = fail_match.group(1)
                test_status_map[test_name] = TestStatus.FAILED.value
    return test_status_map


def parse_log_vitest(log: str) -> dict[str, str]:
    test_status_map = {}
    patterns = [
        # Vitest uses ✓ for passing test files and ❯ for test files with failures
        (r"^✓\s+(.+?)(?:\s+\([\.\d]+ms\))?$", TestStatus.PASSED.value),
        (r"^❯\s+(.+?)(?:\s+\(.*?\))?$", TestStatus.FAILED.value),  # Failed test files
        (r"^✗\s+(.+?)(?:\s+\([\.\d]+ms\))?$", TestStatus.FAILED.value),
        (r"^○\s+(.+?)(?:\s+\([\.\d]+ms\))?$", TestStatus.SKIPPED.value),
        (r"^✓\s+(.+?)$", TestStatus.PASSED.value),
        (r"^✗\s+(.+?)$", TestStatus.FAILED.value),
        (r"^○\s+(.+?)$", TestStatus.SKIPPED.value),
    ]
    for line in log.split("\n"):
        for pattern, status in patterns:
            match = re.match(pattern, line.strip())
            if match:
                test_name = match.group(1).strip()
                # Normalize test file names: extract just the file path before parentheses
                # e.g., "test/foo.test.js (9 tests)" -> "test/foo.test.js"
                # or "test/foo.test.js (9 tests | 5 failed) 22ms" -> "test/foo.test.js"
                if "(" in test_name:
                    test_name = test_name.split("(")[0].strip()
                test_status_map[test_name] = status
                break

    return test_status_map


def parse_log_karma(log: str) -> dict[str, str]:
    """
    Parser for test logs generated by Karma (commonly used with Jasmine/Mocha).
    Since Karma doesn't output individual test names in a parseable way,
    we generate generic test entries based on the summary counts.
    """
    test_status_map = {}

    # Pattern for Karma final summary
    success_pattern = r"Executed\s+(\d+)\s+of\s+\d+\s+SUCCESS"
    failed_pattern = r"Executed\s+\d+\s+of\s+\d+\s+\((\d+)\s+FAILED\)"
    skipped_pattern = r"Executed\s+\d+\s+of\s+(\d+)\s+\((\d+)\s+skipped\)"

    passed_count = 0
    failed_count = 0
    skipped_count = 0

    for line in log.split("\n"):
        success_match = re.search(success_pattern, line)
        if success_match:
            passed_count = max(passed_count, int(success_match.group(1)))

        failed_match = re.search(failed_pattern, line)
        if failed_match:
            failed_count = max(failed_count, int(failed_match.group(1)))

        skipped_match = re.search(skipped_pattern, line)
        if skipped_match:
            skipped_count = max(skipped_count, int(skipped_match.group(2)))

    # Generate test entries
    for i in range(passed_count):
        test_status_map[f"karma_unit_test_{i + 1}"] = TestStatus.PASSED.value

    for i in range(failed_count):
        test_status_map[f"karma_unit_test_failed_{i + 1}"] = TestStatus.FAILED.value

    for i in range(skipped_count):
        test_status_map[f"karma_unit_test_skipped_{i + 1}"] = TestStatus.SKIPPED.value

    return test_status_map


def parse_log_jasmine(log: str) -> dict[str, str]:
    """
    Parser for standalone Jasmine CLI output.
    Format: "426 specs, 0 failures, 3 pending specs"
    """
    test_status_map = {}

    # Pattern for Jasmine summary: "X specs, Y failures, Z pending specs"
    pattern = r"(\d+)\s+specs?,\s+(\d+)\s+failures?(?:,\s+(\d+)\s+pending\s+specs?)?"

    for line in log.split("\n"):
        match = re.search(pattern, line)
        if match:
            total_specs = int(match.group(1))
            failures = int(match.group(2))
            pending = int(match.group(3)) if match.group(3) else 0

            passed = total_specs - failures - pending

            # Generate test entries
            for i in range(passed):
                test_status_map[f"jasmine_spec_{i + 1}"] = TestStatus.PASSED.value

            for i in range(failures):
                test_status_map[f"jasmine_spec_failed_{i + 1}"] = (
                    TestStatus.FAILED.value
                )

            for i in range(pending):
                test_status_map[f"jasmine_spec_pending_{i + 1}"] = (
                    TestStatus.SKIPPED.value
                )

            break  # Only process the first summary line

    return test_status_map


@dataclass
class ReactPDFee5c96b8(JavaScriptProfile):
    owner: str = "diegomura"
    repo: str = "react-pdf"
    commit: str = "ee5c96b80326ba4441b71be4c7a85ba9f61d4174"
    test_cmd: str = "./node_modules/.bin/vitest --no-color --reporter verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-bullseye
RUN apt update && apt install -y pkg-config build-essential libpixman-1-0 libpixman-1-dev libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN yarn install
"""

    def log_parser(self, log: str) -> dict[str, str]:
        test_status_map = {}
        for line in log.split("\n"):
            for pattern, status in [
                (r"^\s*✓\s(.*)\s\d+ms", TestStatus.PASSED.value),
                (r"^\s*✗\s(.*)\s\d+ms", TestStatus.FAILED.value),
                (r"^\s*✖\s(.*)", TestStatus.FAILED.value),
                (r"^\s*✓\s(.*)", TestStatus.PASSED.value),
            ]:
                match = re.match(pattern, line)
                if match:
                    test_name = match.group(1).strip()
                    test_status_map[test_name] = status
                    break
        return test_status_map


@dataclass
class Markeddbf29d91(JavaScriptProfile):
    owner: str = "markedjs"
    repo: str = "marked"
    commit: str = "dbf29d9171a28da21f06122d643baf4e5d4266d4"
    test_cmd: str = "NO_COLOR=1 node --test"

    @property
    def dockerfile(self):
        return f"""FROM node:24-bullseye
RUN apt update && apt install -y git {X11_DEPS}
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
RUN npm test
"""

    def log_parser(self, log: str) -> dict[str, str]:
        test_status_map = {}
        fail_pattern = r"^\s*✖\s(.*?)\s\([\.\d]+ms\)"
        pass_pattern = r"^\s*✔\s(.*?)\s\([\.\d]+ms\)"
        for line in log.split("\n"):
            fail_match = re.match(fail_pattern, line)
            if fail_match:
                test = fail_match.group(1)
                test_status_map[test.strip()] = TestStatus.FAILED.value
            else:
                pass_match = re.match(pass_pattern, line)
                if pass_match:
                    test = pass_match.group(1)
                    test_status_map[test.strip()] = TestStatus.PASSED.value
        return test_status_map


@dataclass
class Babel2ea3fc8f(JavaScriptProfile):
    owner: str = "babel"
    repo: str = "babel"
    commit: str = "2ea3fc8f9b33a911840f17fbc407e7bfae2ed66f"
    test_cmd: str = "yarn jest --verbose"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multilingual"}
    )

    @property
    def dockerfile(self):
        return f"""FROM node:20-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN make bootstrap
RUN make build
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)

    def get_test_cmd(self, instance: dict, f2p_only: bool = False):
        if KEY_PATCH not in instance:
            return self.test_cmd, []
        test_folders = []
        for f in PatchSet(instance[KEY_PATCH]):
            parts = f.path.split("/")
            if len(parts) >= 2 and parts[0] == "packages":
                test_folders.append("/".join(parts[:2]))
        return f"{self.test_cmd} {' '.join(test_folders)}", test_folders


@dataclass
class GithubReadmeStats3e974011(JavaScriptProfile):
    owner: str = "anuraghazra"
    repo: str = "github-readme-stats"
    commit: str = "3e97401177143bb35abb42279a13991cbd584ca3"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Mongoose5f57a5bb(JavaScriptProfile):
    owner: str = "Automattic"
    repo: str = "mongoose"
    commit: str = "5f57a5bbb2e8dfed8d04be47cdd17728633c44c1"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Axiosef36347f(JavaScriptProfile):
    owner: str = "axios"
    repo: str = "axios"
    commit: str = "ef36347fb559383b04c755b07f1a8d11897fab7f"
    test_cmd: str = "npm run test:mocha -- --verbose"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multilingual"}
    )

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Async23dbf76a(JavaScriptProfile):
    owner: str = "caolan"
    repo: str = "async"
    commit: str = "23dbf76aeb04c7c3dd56276115b277e3fa9dd5cc"
    test_cmd: str = "npm run mocha-node-test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Expressef5f2e13(JavaScriptProfile):
    owner: str = "expressjs"
    repo: str = "express"
    commit: str = "ef5f2e13ef64a1575ce8c2d77b180d593644ccfa"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Dayjsc8a26460(JavaScriptProfile):
    owner: str = "iamkun"
    repo: str = "dayjs"
    commit: str = "c8a26460d89a2ee9a7d3b9cafa124ea856ee883f"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name)

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Svelte6c9717a9(JavaScriptProfile):
    owner: str = "sveltejs"
    repo: str = "svelte"
    commit: str = "6c9717a91f2f6ae10641d1cf502ba13d227fbe45"
    test_cmd: str = "pnpm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-bullseye
RUN apt update && apt install -y git
RUN npm install -g pnpm@10.4.0
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN pnpm install
RUN pnpm playwright install chromium
RUN pnpm exec playwright install-deps
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_vitest(log)


@dataclass
class Commanderjs395cf714(JavaScriptProfile):
    owner: str = "tj"
    repo: str = "commander.js"
    commit: str = "395cf7145fe28122f5a69026b310e02df114f907"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="20")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Wretch661865a6(JavaScriptProfile):
    owner: str = "elbywan"
    repo: str = "wretch"
    commit: str = "661865a6642f6be26e742a90a3e0a9b9bd5542ff"
    test_cmd: str = "npm run test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:22-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
RUN npm run build
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Html5Boilerplateac08a17c(JavaScriptProfile):
    owner: str = "h5bp"
    repo: str = "html5-boilerplate"
    commit: str = "ac08a17cb60a975336664c0090657a3e593f686e"
    test_cmd: str = "npm run test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:22-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm ci
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class HighlightJS5697ae51(JavaScriptProfile):
    owner: str = "highlightjs"
    repo: str = "highlight.js"
    commit: str = "5697ae5187746c24732e62cd625f3f83004a44ce"
    test_cmd: str = "npm run test -- --verbose"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multimodal"}
    )

    @property
    def dockerfile(self):
        return f"""FROM node:22-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
RUN npm run build
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Prism31b467fa(JavaScriptProfile):
    owner: str = "PrismJS"
    repo: str = "prism"
    commit: str = "31b467fa7c92c5ce90c3e7c6c8fe2b8a946d9484"
    test_cmd: str = "npm run test"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multimodal"}
    )

    @property
    def dockerfile(self):
        return f"""FROM node:22-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm ci
RUN npm run build
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class ChromaJS498427ea(JavaScriptProfile):
    owner: str = "gka"
    repo: str = "chroma.js"
    commit: str = "498427eafc2e987a3751f8d5fe0612fa7a4a76ec"
    test_cmd: str = "npm run test -- --run"

    @property
    def dockerfile(self):
        return f"""FROM node:22-bullseye
RUN apt update && apt install -y git
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
RUN npm run build
"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_vitest(log)


@dataclass
class Colorfef7b619(JavaScriptProfile):
    owner: str = "Qix-"
    repo: str = "color"
    commit: str = "fef7b619edd678455595b9b6a10780f13b58d285"
    test_cmd: str = "npm run test -- --verbose"

    @property
    def image_name(self) -> str:
        # Note: "-" followed by a "_" is not allowed in Docker image names
        return f"{self.org_dh}/swesmith.{self.arch}.{self.owner.replace('-', '_')}_1776_{self.repo}.{self.commit[:8]}".lower()

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="22")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Qd180f4a0(JavaScriptProfile):
    owner: str = "kriskowal"
    repo: str = "q"
    commit: str = "d180f4a0b22499607ac750b56766c8829d6bff43"
    test_cmd: str = "npm run test -- --verbose --reporter spec"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="22")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class ImmutableJS879adab5(JavaScriptProfile):
    owner: str = "immutable-js"
    repo: str = "immutable-js"
    commit: str = "879adab5ea333a5ca341635bcf799c3b8f9e7559"
    test_cmd: str = "npm run test -- --verbose"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multilingual"}
    )

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="22")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class ThreeJS73b3f248(JavaScriptProfile):
    owner: str = "mrdoob"
    repo: str = "three.js"
    commit: str = "73b3f248016fb73f2fe71da8616cdd7e20386f81"
    test_cmd: str = "npm run test -- --verbose"
    eval_sets: set[str] = field(
        default_factory=lambda: {"SWE-bench/SWE-bench_Multilingual"}
    )

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="22")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Echarts6be0e145(JavaScriptProfile):
    owner: str = "apache"
    repo: str = "echarts"
    commit: str = "6be0e145946db37824c8635067b8b7b23c547b74"
    test_cmd: str = "npm run test -- --verbose"

    @property
    def dockerfile(self):
        return default_npm_install_dockerfile(self.mirror_name, node_version="22")

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Draggable8a1eed57(JavaScriptProfile):
    owner: str = "Shopify"
    repo: str = "draggable"
    commit: str = "8a1eed57f3ab2dff9371e8ce60fb39ac85871e8d"
    test_cmd: str = "yarn test --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN yarn install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Reactslick97442318(JavaScriptProfile):
    owner: str = "akiran"
    repo: str = "react-slick"
    commit: str = "97442318e9a442bd4a84eb25133ef62087f98232"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install system dependencies
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Set the default command
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Pdfmake719e7314(JavaScriptProfile):
    owner: str = "bpampuch"
    repo: str = "pdfmake"
    commit: str = "719e73140cce75a792f7f419c27fc33a230e73d2"
    test_cmd: str = "npm run test"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Multerb6e4b1f6(JavaScriptProfile):
    owner: str = "expressjs"
    repo: str = "multer"
    commit: str = "b6e4b1f6abb85673e9307b42368b3e7bfb1fc63b"
    test_cmd: str = "npm test -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Pdfkitd0108157(JavaScriptProfile):
    owner: str = "foliojs"
    repo: str = "pdfkit"
    commit: str = "d0108157f13d763ad5287a2293436b5a1aecf055"
    test_cmd: str = "yarn test --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    build-essential \
    libcairo2-dev \
    libpango1.0-dev \
    libjpeg-dev \
    libgif-dev \
    librsvg2-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /{ENV_NAME}

# Enable corepack to use the yarn version specified in package.json
RUN corepack enable

# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN yarn install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Mathjs04e6e2d7(JavaScriptProfile):
    owner: str = "josdejong"
    repo: str = "mathjs"
    commit: str = "04e6e2d7a949d6ddc7d7139bf1e3a88e6fe5365b"
    test_cmd: str = "npm run test:src -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install git and other system dependencies if needed
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Build the project (as it seems to have a build step that generates lib/ which might be needed for tests)
RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)  # Default fallback


@dataclass
class Jqueryc28c26ae(JavaScriptProfile):
    owner: str = "jquery"
    repo: str = "jquery"
    commit: str = "c28c26aef0b3238f578690d73703382951cb355d"
    test_cmd: str = "npm run test:browserless -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    python3 \
    make \
    g++ \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Default command
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_qunit(log)


@dataclass
class Koa0a6afa5a(JavaScriptProfile):
    owner: str = "koajs"
    repo: str = "koa"
    commit: str = "0a6afa5a6107c0c8baf4722e29de7566f33d1651"
    test_cmd: str = "node --test"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Layuiabdb748b(JavaScriptProfile):
    owner: str = "layui"
    repo: str = "layui"
    commit: str = "abdb748b5cc792c394fbdf56daa2727af1846488"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install git
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Mocha410ce0d2(JavaScriptProfile):
    owner: str = "mochajs"
    repo: str = "mocha"
    commit: str = "410ce0d2a0f799aaca2c0bc627294d70c62dd3f4"
    test_cmd: str = "npm run test-node:unit"

    @property
    def dockerfile(self):
        return f"""FROM node:22-slim

# Install git
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Set the default command
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Reactnativeweba9de220b(JavaScriptProfile):
    owner: str = "necolas"
    repo: str = "react-native-web"
    commit: str = "a9de220ba9e65bdea540fb5322ffb1da2b0bf442"
    test_cmd: str = "npm run unit:dom -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    && rm -rf /var/lib/apt/lists/*

# Set working directory

# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Set default command
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Piskel51373322(JavaScriptProfile):
    owner: str = "piskelapp"
    repo: str = "piskel"
    commit: str = "513733227695da58780a4df30f44e4af9f85b1a6"
    test_cmd: str = "npm run unit-tests"

    @property
    def dockerfile(self):
        return f"""FROM node:18-bullseye-slim

# Install system dependencies for Playwright and Puppeteer
RUN apt-get update && apt-get install -y \
    git \
    libnss3 \
    libdbus-1-3 \
    libatk1.0-0 \
    libatk-bridge2.0-0 \
    libcups2 \
    libdrm2 \
    libxcomposite1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxrandr2 \
    libgbm1 \
    libasound2 \
    libpangocairo-1.0-0 \
    libx11-6 \
    libxkbcommon0 \
    libpango-1.0-0 \
    libcairo2 \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Install Playwright browsers and their dependencies
RUN npx playwright install --with-deps chromium

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_karma(log)


@dataclass
class Reduxsagaa4ace10d(JavaScriptProfile):
    owner: str = "redux-saga"
    repo: str = "redux-saga"
    commit: str = "a4ace10dc3ff182828cd3ee7469f6667e08ceb62"
    test_cmd: str = "yarn test --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install git for cloning and patching
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies using yarn (yarn.lock is present)
RUN yarn install --frozen-lockfile

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Riot32aecfaa(JavaScriptProfile):
    owner: str = "riot"
    repo: str = "riot"
    commit: str = "32aecfaa424609ba35829f645138f182f3273dce"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y \
    git \
    make \
    procps \
    && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Svgoc06d8f68(JavaScriptProfile):
    owner: str = "svg"
    repo: str = "svgo"
    commit: str = "c06d8f6899788defae9594537063c2f4307803e4"
    test_cmd: str = "yarn cross-env NODE_OPTIONS=--experimental-vm-modules jest --maxWorkers=4 --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install git for cloning the repository
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Enable corepack to use the yarn version specified in package.json and install dependencies
RUN corepack enable && yarn install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Bruno80e09d1a(JavaScriptProfile):
    owner: str = "usebruno"
    repo: str = "bruno"
    commit: str = "80e09d1a267ed2283e6d58a643800d3d632372a7"
    test_cmd: str = "npm test --workspaces --if-present -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:22-slim

RUN apt-get update && apt-get install -y git python3 make g++ && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm run setup

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Webtorrentfd8f39e1(JavaScriptProfile):
    owner: str = "webtorrent"
    repo: str = "webtorrent"
    commit: str = "fd8f39e1560c5ae5db6b12153077877f0f33b076"
    test_cmd: str = "npx tape test/*.js test/node/*.js"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies for native modules
RUN apt-get update && apt-get install -y \
    python3 \
    make \
    g++ \
    git \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Whydidyourender3ec3512d(JavaScriptProfile):
    owner: str = "welldone-software"
    repo: str = "why-did-you-render"
    commit: str = "3ec3512d750c49448fe2241e26d05db9e42f0c21"
    test_cmd: str = "yarn test --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN yarn install

# Keep the container running
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Eleventye9a16667(JavaScriptProfile):
    owner: str = "11ty"
    repo: str = "eleventy"
    commit: str = "e9a16667cbf44226d4dc88ac18241003e05908d2"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["npm", "test"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Workbox1893b3f6(JavaScriptProfile):
    owner: str = "GoogleChrome"
    repo: str = "workbox"
    commit: str = "1893b3f6ca3d82338f18acc84309f2f38fc67292"
    test_cmd: str = "npm run test_node -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies required for building some native modules and git for cloning
RUN apt-get update && apt-get install -y git python3 make g++ && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies and build the project (required for tests to find built modules)
RUN npm ci && npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Habiticae0af620b(JavaScriptProfile):
    owner: str = "HabitRPG"
    repo: str = "habitica"
    commit: str = "e0af620b4045d46dffb4c22ea01f95ba8a8af009"
    test_cmd: str = "npm run test:api:unit -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:20

RUN apt-get update && apt-get install -y git python3 build-essential && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# The postinstall script in package.json handles:
# 1. gulp build
# 2. cd website/client && npm install
# We need to ensure dependencies for the main app are installed first.
# Also, Habitica expects a config.json file.
RUN cp config.json.example config.json
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Modernizr1d4c9cee(JavaScriptProfile):
    owner: str = "Modernizr"
    repo: str = "Modernizr"
    commit: str = "1d4c9cee1f358f50c31be9a1f247e1153ed9143c"
    test_cmd: str = "npm test -- --verbose --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

# Install system dependencies including git and chromium for puppeteer/mocha-headless-chrome
RUN apt-get update && apt-get install -y \
    git \
    wget \
    gnupg \
    ca-certificates \
    chromium \
    --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies, skipping puppeteer browser download since we use system chromium
ENV PUPPETEER_SKIP_DOWNLOAD=true
ENV CHROME_PATH=/usr/bin/chromium
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
RUN npm install

# Set CMD
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Falcor39d64776(JavaScriptProfile):
    owner: str = "Netflix"
    repo: str = "falcor"
    commit: str = "39d64776cf9d87781b2791615dcbae73b2bcd2e1"
    test_cmd: str = "npm run test:only -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install --legacy-peer-deps

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Pm2ff1ca974(JavaScriptProfile):
    owner: str = "Unitech"
    repo: str = "pm2"
    commit: str = "ff1ca974afada8730aa55f8ed1df40e700cedbcb"
    test_cmd: str = "npm run test:unit -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git procps bc python3 && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Audiobookshelf626596b1(JavaScriptProfile):
    owner: str = "advplyr"
    repo: str = "audiobookshelf"
    commit: str = "626596b192013ba9f5a011dd110e288124c95ebe"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-bullseye-slim

RUN apt-get update && apt-get install -y \
    git \
    python3 \
    make \
    g++ \
    ffmpeg \
    && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install root dependencies
RUN npm ci

# Install client dependencies and build client
RUN cd client && npm ci && npm run generate

# Ensure we are back in root
WORKDIR /{ENV_NAME}

CMD ["npm", "start"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Sailsffebacc5(JavaScriptProfile):
    owner: str = "balderdashy"
    repo: str = "sails"
    commit: str = "ffebacc58c27f878c9373702bc3a3f91a02bca0c"
    test_cmd: str = "npm run custom-tests -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Vuebootstrapvue9a246f45(JavaScriptProfile):
    owner: str = "bootstrap-vue"
    repo: str = "bootstrap-vue"
    commit: str = "9a246f45fc813f161df291fc7d6197febf8afaf4"
    test_cmd: str = "yarn jest --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-bullseye-slim

RUN apt-get update && apt-get install -y git python3 make g++ && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN chmod u+x scripts/build.sh
RUN yarn install --frozen-lockfile

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Nodepostgresecff60dc(JavaScriptProfile):
    owner: str = "brianc"
    repo: str = "node-postgres"
    commit: str = "ecff60dc8aa0bd1ad5ea8f4623af0756a86dc110"
    test_cmd: str = "service postgresql start && sleep 5 && sudo -u postgres psql -c \"ALTER USER postgres WITH PASSWORD 'postgres';\" && export PGPASSWORD=postgres && export PGUSER=postgres && export PGHOST=localhost && yarn test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y \
    git \
    make \
    python3 \
    g++ \
    build-essential \
    libpq-dev \
    postgresql \
    postgresql-contrib \
    sudo \
    && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN yarn install
RUN yarn build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Claudecodetemplates734b8a50(JavaScriptProfile):
    owner: str = "davila7"
    repo: str = "claude-code-templates"
    commit: str = "734b8a50cc2cf55222643e32a3b205483e244747"
    test_cmd: str = "cd api && npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install && \
    cd cli-tool && npm install && \
    cd ../api && npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Jsemotionb882bcba(JavaScriptProfile):
    owner: str = "emotion-js"
    repo: str = "emotion"
    commit: str = "b882bcba85132554992e4bd49e94c95939bbf810"
    test_cmd: str = "yarn jest --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git python3 build-essential && rm -rf /var/lib/apt/lists/*

RUN corepack enable


RUN git clone --depth 1 https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN yarn install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Enzyme61e1b47c(JavaScriptProfile):
    owner: str = "enzymejs"
    repo: str = "enzyme"
    commit: str = "61e1b47c4bdc4509b2ac286c0d3ae3df172d26f0"
    test_cmd: str = "npm run react 16 && npm run test:only -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y \
    git \
    python3 \
    make \
    g++ \
    && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Recoilc1b97f3a(JavaScriptProfile):
    owner: str = "facebookexperimental"
    repo: str = "Recoil"
    commit: str = "c1b97f3a0117cad76cbc6ab3cb06d89a9ce717af"
    test_cmd: str = "yarn relay"

    @property
    def dockerfile(self):
        return f"""FROM node:18

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN yarn install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Superagentcec26064(JavaScriptProfile):
    owner: str = "forwardemail"
    repo: str = "superagent"
    commit: str = "cec260643d6d8854865cf6a18997606be4b150f6"
    test_cmd: str = "./node_modules/.bin/mocha --require should --trace-warnings --throw-deprecation --reporter spec --slow 2000 --timeout 5000 --exit test/*.js test/node/*.js"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git build-essential python3 && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Supertest14d905dc(JavaScriptProfile):
    owner: str = "forwardemail"
    repo: str = "supertest"
    commit: str = "14d905dc313b7c050596342f833a52f0bc573c70"
    test_cmd: str = "npm test -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["npm", "test"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Revealjsbecc9bd1(JavaScriptProfile):
    owner: str = "hakimel"
    repo: str = "reveal.js"
    commit: str = "becc9bd19e418b75027b541c41952105a1425c96"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies for git and Puppeteer
RUN apt-get update && apt-get install -y \
    git \
    ca-certificates \
    fonts-liberation \
    libasound2 \
    libatk-bridge2.0-0 \
    libatk1.0-0 \
    libc6 \
    libcairo2 \
    libcups2 \
    libdbus-1-3 \
    libexpat1 \
    libfontconfig1 \
    libgbm1 \
    libgcc1 \
    libglib2.0-0 \
    libgtk-3-0 \
    libnspr4 \
    libnss3 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libstdc++6 \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    lsb-release \
    wget \
    xdg-utils \
    --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Build the project (some tests might depend on built assets)
RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Handsontablee71f0f42(JavaScriptProfile):
    owner: str = "handsontable"
    repo: str = "handsontable"
    commit: str = "e71f0f427c43eaaac9362d947270b8856a9766cd"
    test_cmd: str = "pnpm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git python3 make g++ && rm -rf /var/lib/apt/lists/*

RUN npm install -g pnpm@10.12.2


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN pnpm install && pnpm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Joi481e270e(JavaScriptProfile):
    owner: str = "hapijs"
    repo: str = "joi"
    commit: str = "481e270e6c4ff8728d6fda248fd83f6ff70f7ed9"
    test_cmd: str = "npx lab -t 100 -a @hapi/code -L -Y -v"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Impressjsc9f6c674(JavaScriptProfile):
    owner: str = "impress"
    repo: str = "impress.js"
    commit: str = "c9f6c67457ceee5a011e554f67c447113640777d"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:18

RUN apt-get update && apt-get install -y \
    git \
    wget \
    gnupg \
    ca-certificates \
    libgconf-2-4 \
    libatk1.0-0 \
    libatk-bridge2.0-0 \
    libgdk-pixbuf2.0-0 \
    libgtk-3-0 \
    libgbm-dev \
    libnss3 \
    libxss1 \
    libasound2 \
    libxtst6 \
    xfonts-75dpi \
    xfonts-base \
    fonts-liberation \
    libappindicator3-1 \
    lsb-release \
    xdg-utils \
    libx11-xcb1 \
    libxcb-dri3-0 \
    --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jasmine(log)


@dataclass
class Htmlwebpackplugin9a39db80(JavaScriptProfile):
    owner: str = "jantimon"
    repo: str = "html-webpack-plugin"
    commit: str = "9a39db807c09d8e6145e5047cfe2ec5e928e1dee"
    test_cmd: str = "npm run test:only -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install --legacy-peer-deps

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Backbonee8bc45ac(JavaScriptProfile):
    owner: str = "jashkenas"
    repo: str = "backbone"
    commit: str = "e8bc45acb0a8b035fe5a0d7338e1b2757681564f"
    test_cmd: str = "npx karma start --browsers ChromeHeadlessNoSandbox --single-run"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git chromium && rm -rf /var/lib/apt/lists/*

ENV CHROME_BIN=/usr/bin/chromium


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install && npm install karma-chrome-launcher --save-dev

# Add ChromeHeadlessNoSandbox launcher to karma.conf.js
RUN sed -i "s/customLaunchers: {{/customLaunchers: {{\\n        ChromeHeadlessNoSandbox: {{\\n            base: 'ChromeHeadless',\\n            flags: ['--no-sandbox']\\n        }},/" karma.conf.js

# Build debug-info.js which is required by tests
RUN npm run build-debug

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jasmine(log)


@dataclass
class Hyperapp5a113fa0(JavaScriptProfile):
    owner: str = "jorgebucaran"
    repo: str = "hyperapp"
    commit: str = "5a113fa00450302be9234e0a74ee634ed5574243"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Jsoneditor0319b213(JavaScriptProfile):
    owner: str = "josdejong"
    repo: str = "jsoneditor"
    commit: str = "0319b2131df47f1220d74e3ff174d5c02973ec7d"
    test_cmd: str = "npm test -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Uptimekuma5d955f95(JavaScriptProfile):
    owner: str = "louislam"
    repo: str = "uptime-kuma"
    commit: str = "5d955f954b60410cd2dc5370d429753de524a2ef"
    test_cmd: str = "npm run test-backend"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    python3 \
    build-essential \
    iputils-ping \
    && rm -rf /var/lib/apt/lists/*


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Build the frontend
RUN npm run build

# Default command
CMD ["npm", "start"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Jsmarko24b9402c(JavaScriptProfile):
    owner: str = "marko-js"
    repo: str = "marko"
    commit: str = "24b9402cd54c3a74f200da0f79dd19350995a9ba"
    test_cmd: str = "env MARKO_DEBUG=1 ./node_modules/.bin/mocha --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git python3 build-essential && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install && npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Jsmdx00046053(JavaScriptProfile):
    owner: str = "mdx-js"
    repo: str = "mdx"
    commit: str = "000460532e6a558693cbe73c2ffdb8d6c098a07b"
    test_cmd: str = "npm run test-api --workspaces --if-present"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class PapaParseb10b87ef(JavaScriptProfile):
    owner: str = "mholt"
    repo: str = "PapaParse"
    commit: str = "b10b87ef8686c6f88299b50dd25e83606e9c36d4"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y \
    git \
    chromium \
    && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
RUN sed -i "s/'-f'/'-a', '[\"--no-sandbox\"]', '-f'/" tests/test.js

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Materialui1a233f88(JavaScriptProfile):
    owner: str = "mui"
    repo: str = "material-ui"
    commit: str = "1a233f8805ea20f456afd41165b1d6d9e22c0adb"
    test_cmd: str = "pnpm test:node run"

    @property
    def dockerfile(self):
        return f"""FROM node:22-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN npm install -g pnpm@10.25.0


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN pnpm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_vitest(log)


@dataclass
class Nightwatch54c8550c(JavaScriptProfile):
    owner: str = "nightwatchjs"
    repo: str = "nightwatch"
    commit: str = "54c8550c75a16c61827c0bad043c7ffa073a52e6"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install --ignore-scripts

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Nocke7418da2(JavaScriptProfile):
    owner: str = "nock"
    repo: str = "nock"
    commit: str = "e7418da29feb4a7bf0aa1612bfb9d32a4051651e"
    test_cmd: str = "npm test -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:20

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class NoVNCd44f7e04(JavaScriptProfile):
    owner: str = "novnc"
    repo: str = "noVNC"
    commit: str = "d44f7e04fc456844836c7c5ac911d0f4e8dd06e6"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    chromium \
    ca-certificates \
    --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

# Create a wrapper for chromium to always include --no-sandbox
RUN mv /usr/bin/chromium /usr/bin/chromium-orig && \
    echo -e '#!/bin/bash\\n/usr/bin/chromium-orig --no-sandbox "$@"' > /usr/bin/chromium && \
    chmod +x /usr/bin/chromium

# Set environment variables
ENV CHROME_BIN=/usr/bin/chromium
ENV TEST_BROWSER_NAME=ChromeHeadless


# Clone the repository
RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

# Install dependencies
RUN npm install

# Command to keep container running
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class JsPDFe6cf03db(JavaScriptProfile):
    owner: str = "parallax"
    repo: str = "jsPDF"
    commit: str = "e6cf03db2499ef0a9ccc54b2aba45156c5b32b3c"
    test_cmd: str = "npm run test-node"

    @property
    def dockerfile(self):
        return rf"""FROM node:18

RUN apt-get update && apt-get install -y \
    git \
    libnss3 \
    libatk-bridge2.0-0 \
    libx11-xcb1 \
    libxcb-dri3-0 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxtst6 \
    libcups2 \
    libdbus-1-3 \
    libexpat1 \
    libfontconfig1 \
    libgbm1 \
    libgcc1 \
    libglib2.0-0 \
    libgtk-3-0 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libstdc++6 \
    libv4l-0 \
    libxkbcommon0 \
    libasound2 \
    wget \
    gnupg \
    --no-install-recommends \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
    && apt-get update \
    && apt-get install -y google-chrome-stable --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

ENV CHROME_BIN=/usr/bin/google-chrome-stable


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

# Inject custom launcher into karma.conf.js
RUN sed -i "s/browsers: \\['Chrome'\\]/browsers: ['ChromeHeadlessNoSandbox']/" test/unit/karma.conf.js && \
    sed -i "/reporters: \\[/i     customLaunchers: {{\\n      ChromeHeadlessNoSandbox: {{\\n        base: 'ChromeHeadless',\\n        flags: ['--no-sandbox', '--disable-setuid-sandbox']\\n      }}\\n    }}," test/unit/karma.conf.js

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Filepond38294959(JavaScriptProfile):
    owner: str = "pqina"
    repo: str = "filepond"
    commit: str = "38294959147229eb09126008fc09d295da4e30cd"
    test_cmd: str = "npm test -- --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Reacttransitiongroup2989b5b8(JavaScriptProfile):
    owner: str = "reactjs"
    repo: str = "react-transition-group"
    commit: str = "2989b5b87b4b4d1001f21c8efa503049ffb4fe8d"
    test_cmd: str = "npm run testonly"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install --legacy-peer-deps

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Reactmarkdownfda7fa56(JavaScriptProfile):
    owner: str = "remarkjs"
    repo: str = "react-markdown"
    commit: str = "fda7fa560bec901a6103e195f9b1979dab543b17"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Nodemondaad5c16(JavaScriptProfile):
    owner: str = "remy"
    repo: str = "nodemon"
    commit: str = "daad5c162919fa6abff53be16832bdf55f2204ad"
    test_cmd: str = "for FILE in test/**/*.test.js; do echo $FILE; TEST=1 ./node_modules/.bin/mocha --exit --timeout 30000 $FILE || true; sleep 1; done"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Evergreen9b774aee(JavaScriptProfile):
    owner: str = "segmentio"
    repo: str = "evergreen"
    commit: str = "9b774aee2d794f6cf2f73a054bd33066ca5898a9"
    test_cmd: str = "yarn jest --verbose"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN yarn install --frozen-lockfile

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Serverlessde62c71e(JavaScriptProfile):
    owner: str = "serverless"
    repo: str = "serverless"
    commit: str = "de62c71e30855eff688f032ff10b9ad22de13afc"
    test_cmd: str = "npm test -- --reporter spec"

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install
CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Jssqljs52e5649f(JavaScriptProfile):
    owner: str = "sql-js"
    repo: str = "sql.js"
    owner: str = "sql-js"
    repo: str = "sql.js"
    commit: str = "52e5649f3a3a2a46aa4ad58a79d118c22f56cf30"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM emscripten/emsdk:latest

RUN apt-get update && apt-get install -y git make python3 unzip curl libdigest-sha3-perl && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN npm install
RUN npm run build

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Jsonserverf5dfdaff(JavaScriptProfile):
    owner: str = "typicode"
    repo: str = "json-server"
    commit: str = "f5dfdaff725ecd5384b1f922b37757f023e13b63"
    test_cmd: str = "npm test"

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install
CMD ["npm", "start"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


@dataclass
class Webpack24e3c2d2(JavaScriptProfile):
    owner: str = "webpack"
    repo: str = "webpack"
    commit: str = "24e3c2d2c9f8c6d60810302b2ea70ed86e2863dc"
    test_cmd: str = (
        "yarn test:base --verbose --testMatch '<rootDir>/test/*.basictest.js'"
    )

    @property
    def dockerfile(self):
        return f"""FROM node:20-slim

RUN apt-get update && apt-get install -y git python3 build-essential && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}

RUN yarn install && yarn setup

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_jest(log)


@dataclass
class Ws726c3732(JavaScriptProfile):
    owner: str = "websockets"
    repo: str = "ws"
    commit: str = "726c3732b3e5319219ed73cac4826fd36917e2e1"
    test_cmd: str = "npm test -- --reporter spec"
    timeout: int = 300

    @property
    def dockerfile(self):
        return f"""FROM node:18-slim

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*


RUN git clone https://github.com/{self.mirror_name} /{ENV_NAME}
WORKDIR /{ENV_NAME}
RUN npm install

CMD ["/bin/bash"]"""

    def log_parser(self, log: str) -> dict[str, str]:
        return parse_log_mocha(log)


# Register all JavaScript profiles with the global registry
for name, obj in list(globals().items()):
    if (
        isinstance(obj, type)
        and issubclass(obj, JavaScriptProfile)
        and obj.__name__ != "JavaScriptProfile"
    ):
        registry.register_profile(obj)


# Register all JavaScript profiles with the global registry
for name, obj in list(globals().items()):
    if (
        isinstance(obj, type)
        and issubclass(obj, JavaScriptProfile)
        and obj.__name__ != "JavaScriptProfile"
    ):
        registry.register_profile(obj)
