npm / playwright / 1.65.0-alpha-2026-10-24

playwright 1.65.0-alpha-2026-10-24

Source
https://github.com/microsoft/playwright
Artifact scanned
playwright-1.65.0-alpha-2026-10-24.tgz (npm tarball · 887.8 KB · SHA-256 8ead52b6ade8…)
Compared with
playwright-1.65.0-alpha-2026-10-23.tgz (1 signals introduced since)
Files
55 scanned, 5 skipped (binary, oversized, or unrecognised)
Signals
0 critical · 0 warn · 60 info
Scan time
33.7 s
LLM review
Reviewed by claude-haiku-5-5 (Anthropic): 32 of 32 warn and critical signals; 32 demoted to info.
Disclude version
4.3.0
Scanned (UTC)
2026-10-24 10:28

Signals

Ordered by severity, then signals introduced in this release. Hidden characters are shown as ⟨U+…⟩.

  1. info long-line README.md:3:1 new in this release

    line length 742 characters (raw pass, confidence 0.50)

    [![npm version]https://img.shields.io/npm/v/playwright.svg]https://www.npmjs.com/package/playwright <!-- GEN:chromium-version-badge -->[![Chromium version]https://img.shields.io/badge/chromium-157.0.8103.15-blue.svg?logo=google-chrome]https://www.chromium.org/Home<!-- GEN:stop --> <!-- GEN:firefox-version-badge
  2. info warn → info by review dynamic-import lib/common/index.js:1124:30

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

      process.env.BROWSERSLIST_IGNORE_OLD_DATA = "true";
      const { babelTransform } = require((0, import_package3.libPath)("transform", "babelBundle"));
      const babelResult = babelTransform(originalCode, filename, !!moduleUrl, pluginsEpilogue, useDefineForClassFields, jsx);
      if (!babelResult?.code)
    likely benign LLM, confidence 0.85 Loads the bundled Babel transform module from the package's own lib directory.
    Reasoning

    The non-literal require resolves a path via libPath("transform", "babelBundle") inside the package's own lib directory. The result feeds a Babel transform of user test source. This is the bundler's internal loader, not a payload fetch.

  3. info critical → info by review dynamic-execution lib/common/index.js:1141:29

    `eval` called with a non-literal expression (ast pass, confidence 0.90)

        const fileName = import_url2.default.pathToFileURL(file);
        const esmImport = () => eval(`import(${JSON.stringify(fileName)})`);
        if (loaderChannel) {
    likely benign LLM, confidence 0.80 Uses eval to perform a dynamic ESM import of a test file by file URL.
    Reasoning

    eval wraps a dynamic import() of a file URL built with JSON.stringify from a local test file path. This is a known way to load ESM test files without transpiling them. The eval is used for module loading, not decoding or fetching remote code.

  4. info critical → info by review dynamic-execution lib/common/index.js:1143:13

    `eval` called with a non-literal expression (ast pass, confidence 0.90)

        if (loaderChannel) {
          await eval(`import(${JSON.stringify(fileName + ".esm.preflight")})`).catch((error) => debugTest("Failed to load preflight for " + file + ", source maps may be missing for errors thrown during loading.", error)).finally(nextTask);
        }
        return await esmImport().finally(nextTask);
    likely benign LLM, confidence 0.80 Eval-based dynamic import of an optional local preflight module for source maps.
    Reasoning

    Same eval(import(...)) pattern, loading an optional '.esm.preflight' sibling of the test file for source-map setup. It is local and error-tolerant, consistent with a test runner's loader.

  5. info warn → info by review dynamic-import lib/common/index.js:1147:18

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

      }
      const result = require(file);
      const depsCollector = currentFileDepsCollector();
      if (depsCollector) {
    likely benign LLM, confidence 0.85 Requires a test file by path inside the runner's loader.
    Reasoning

    require(file) loads the test file path chosen by the runner, inside a dependency-collector context. This is the CommonJS equivalent of the ESM loader and is expected in a test runner.

  6. line length 572 characters (raw pass, confidence 0.50)

          return "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE |
  7. line length 997 characters (raw pass, confidence 0.50)

          var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* 
  8. line length 574 characters (raw pass, confidence 0.50)

            return "string" === typeof type || "function" === typeof type || type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" === typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE
  9. line length 638 characters (raw pass, confidence 0.50)

        exports2.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-
  10. info warn → info by review long-line lib/matchers/expect.js:5876:1

    line length 2269 characters (raw pass, confidence 0.65)

        var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 
    dismissed LLM, confidence 0.90 Very long line holding a generated Unicode identifier-range table in a bundled matcher library.
    Reasoning

    A raw-pass long-line finding on a bundled data table of Unicode identifier code points. This is minified or generated data and a known false-positive class for raw line-length checks.

  11. info warn → info by review dynamic-import lib/matchers/expect.js:10242:44

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

                  const moduleUrl = (0, _nodeUrl().pathToFileURL)(filePath);
                  const importedModule = await import(
                    /* webpackIgnore: true */
                    moduleUrl.href
    likely benign LLM, confidence 0.80 Dynamic import of a local file's URL inside a bundled module loader.
    Reasoning

    Dynamic import of a path converted from a local file path via pathToFileURL, with a webpackIgnore hint. This is the standard module loader used by a test or assertion library for config or module loading.

  12. info warn → info by review dynamic-import lib/matchers/expect.js:10268:38

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

                  }
                  const requiredModule = require(filePath);
                  if (!applyInteropRequireDefault) {
                    return requiredModule;
    likely benign LLM, confidence 0.80 CommonJS require of a local module path in a loader helper.
    Reasoning

    CommonJS require of a local filePath, with an interop fallback. This is a standard module-loading helper that returns the loaded module, with no decoding or network access.

  13. line length 543 characters (raw pass, confidence 0.50)

        const message = pass ? () => matcherHint(matcherName, void 0, void 0, options) + "\n\n" + printExpectedConstructorNameNot("Expected constructor", expected) + (typeof received.constructor === "function" && received.constructor !== expected ? printReceivedConstructorNameNot("Received constructor", received.constructo
  14. line length 766 characters (raw pass, confidence 0.50)

      const message = pass ? () => matcherHint(matcherName, void 0, void 0, options) + "\n\n" + formatExpected("Expected asymmetric matcher: not ", expected) + "\n" + (thrown !== null && thrown.hasMessage ? formatReceived("Received name:    ", thrown, "name") + formatReceived("Received message: ", thrown, "message") + form
  15. line length 539 characters (raw pass, confidence 0.50)

      const message = pass ? () => matcherHint(matcherName, void 0, void 0, options) + "\n\n" + formatExpected(`Expected ${messageAndCause(expected)}: not `, expectedMessageAndCause) + (thrown !== null && thrown.hasMessage ? formatStack(thrown) : formatReceived("Received value:       ", thrown, "value")) : () => matcherHin
  16. line length 756 characters (raw pass, confidence 0.50)

      const message = pass ? () => matcherHint(matcherName, void 0, void 0, options) + "\n\n" + printExpectedConstructorNameNot("Expected constructor", expected) + (thrown !== null && thrown.value !== null && thrown.value !== void 0 && typeof thrown.value.constructor === "function" && thrown.value.constructor !== expected 
  17. info warn → info by review dynamic-import lib/package.js:38:21

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

    const packageRoot = import_path.default.join(__dirname, "..");
    const packageJSON = require(import_path.default.join(packageRoot, "package.json"));
    function libPath(...parts) {
      return import_path.default.join(packageRoot, "lib", ...parts);
    likely benign LLM, confidence 0.90 Reads the package's own package.json through require.
    Reasoning

    Requires the package's own package.json via a path joined from __dirname. This is a fixed, self-referential read of metadata.

  18. info warn → info by review dynamic-execution lib/runner/index.js:272:80

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

      _onStdIO(type, testId, resultId, data, isBase64) {
        const chunk = isBase64 ? globalThis.Buffer ? Buffer.from(data, "base64") : atob(data) : data;
        const test = testId ? this._tests.get(testId) : void 0;
        const result = test && resultId ? test.results.find((r) => r._id === resultId) : void 0;
    likely benign LLM, confidence 0.75 Decodes base64 stdout/stderr chunks from test workers for reporting.
    Reasoning

    atob decodes base64 stdio chunks forwarded from worker processes into output text. The decoded data is only used as a log chunk and is never evaluated or fetched. This is ordinary data transport in a test runner.

  19. info warn → info by review dynamic-import lib/runner/index.js:3242:27

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

          const resolveFrom = (name) => require.resolve(name, { paths: [this._options.configDir] });
          const libCoverage = require(resolveFrom("istanbul-lib-coverage"));
          const libReport = require(resolveFrom("istanbul-lib-report"));
          const reports = require(resolveFrom("istanbul-reports"));
    likely benign LLM, confidence 0.85 Loads the istanbul-lib-coverage package resolved from the config directory.
    Reasoning

    Requires the istanbul coverage library, resolved with require.resolve from the user's configured config directory. This is the normal way a test runner loads optional coverage tooling.

  20. info warn → info by review dynamic-import lib/runner/index.js:3243:25

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

          const libCoverage = require(resolveFrom("istanbul-lib-coverage"));
          const libReport = require(resolveFrom("istanbul-lib-report"));
          const reports = require(resolveFrom("istanbul-reports"));
          const context = libReport.createContext({
    likely benign LLM, confidence 0.85 Loads the istanbul-lib-report package for coverage reporting.
    Reasoning

    Loads istanbul-lib-report via resolved path for HTML or coverage reporting. The module names are fixed and the path resolution is standard, with no payload or network activity.

  21. info warn → info by review dynamic-import lib/runner/index.js:3244:23

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

          const libReport = require(resolveFrom("istanbul-lib-report"));
          const reports = require(resolveFrom("istanbul-reports"));
          const context = libReport.createContext({
            dir: outputDir,
    likely benign LLM, confidence 0.85 Loads the istanbul-reports package for generating coverage reports.
    Reasoning

    Loads istanbul-reports via resolved path to build coverage reports. The reporting-library pattern is legitimate and the module names are fixed.

  22. info whitespace-anomaly lib/transform/babelBundle.js:9:1

    file mixes tab and space indentation (10 tab-indented and 71066 space-indented lines) (raw pass, confidence 0.40)

    var __commonJS = (cb, mod) => function __require() {
      try {
        return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
      } catch (e) {
  23. info warn → info by review long-line lib/transform/babelBundle.js:3079:1

    line length 2269 characters (raw pass, confidence 0.65)

        var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 
    likely benign LLM, confidence 0.92 A long numeric array of Unicode identifier code points in a bundled Babel library.
    Reasoning

    The long line is a plain array of astral identifier code points from Babel's identifier tables, a normal output of a bundled parser. Nothing executes or decodes it, so it is a formatting artifact.

  24. line length 584 characters (raw pass, confidence 0.50)

        exports2.UPDATE_OPERATORS = exports2.UNARY_OPERATORS = exports2.STRING_UNARY_OPERATORS = exports2.STATEMENT_OR_BLOCK_KEYS = exports2.NUMBER_UNARY_OPERATORS = exports2.NUMBER_BINARY_OPERATORS = exports2.LOGICAL_OPERATORS = exports2.INHERIT_KEYS = exports2.FOR_INIT_KEYS = exports2.FLATTENABLE_KEYS = exports2.EQUALITY
  25. info warn → info by review long-line lib/transform/babelBundle.js:10081:1

    line length 2864 characters (raw pass, confidence 0.65)

        exports2.JSXIdentifier = exports2.JSXFragment = exports2.JSXExpressionContainer = exports2.JSXEmptyExpression = exports2.JSXElement = exports2.JSXClosingFragment = exports2.JSXClosingElement = exports2.JSXAttribute = exports2.IntersectionTypeAnnotation = exports2.InterpreterDirective = exports2.InterfaceTypeAnnotat
    likely benign LLM, confidence 0.93 A long generated list of Babel AST node-type exports.
    Reasoning

    This is a long chain of exports assignments for Babel AST node types, typical of generated module export lists. It has no executable payload.

  26. info warn → info by review long-line lib/transform/babelBundle.js:10082:1

    line length 2895 characters (raw pass, confidence 0.65)

        exports2.TSNumberKeyword = exports2.TSNullKeyword = exports2.TSNonNullExpression = exports2.TSNeverKeyword = exports2.TSNamespaceExportDeclaration = exports2.TSNamedTupleMember = exports2.TSModuleDeclaration = exports2.TSModuleBlock = exports2.TSMethodSignature = exports2.TSMappedType = exports2.TSLiteralType = exp
    likely benign LLM, confidence 0.93 A long generated list of TypeScript AST node-type exports.
    Reasoning

    Same pattern as the neighbouring finding: a generated export list of TypeScript AST node types inside a bundled Babel build.

  27. line length 1618 characters (raw pass, confidence 0.50)

        exports2.YieldExpression = exports2.WithStatement = exports2.WhileStatement = exports2.VoidTypeAnnotation = exports2.VoidPattern = exports2.Variance = exports2.VariableDeclarator = exports2.VariableDeclaration = exports2.V8IntrinsicIdentifier = exports2.UpdateExpression = exports2.UnionTypeAnnotation = exports2.Una
  28. line length 1460 characters (raw pass, confidence 0.50)

        exports2.WHILE_TYPES = exports2.USERWHITESPACABLE_TYPES = exports2.UNARYLIKE_TYPES = exports2.TYPESCRIPT_TYPES = exports2.TSTYPE_TYPES = exports2.TSTYPEELEMENT_TYPES = exports2.TSENTITYNAME_TYPES = exports2.TSBASETYPE_TYPES = exports2.TERMINATORLESS_TYPES = exports2.STATEMENT_TYPES = exports2.STANDARDIZED_TYPES = e
  29. info warn → info by review long-line lib/transform/babelBundle.js:15700:1

    line length 2269 characters (raw pass, confidence 0.65)

        var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 
    likely benign LLM, confidence 0.92 A duplicate of the Babel astral identifier code-point table.
    Reasoning

    This duplicates the identifier-table array seen earlier in the bundle, which is standard Babel Unicode data. It is not obfuscation.

  30. line length 509 characters (raw pass, confidence 0.50)

        var reservedWordLikeSet = /* @__PURE__ */ new Set(["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "fals
  31. line length 825 characters (raw pass, confidence 0.50)

            var _node$directive, _node$decorators, _node$optional, _node$typeAnnotation, _node$accessibility, _node$decorators2, _node$override, _node$readonly, _node$static, _node$declare, _node$returnType, _node$typeParameters, _node$optional2, _node$optional3, _node$accessibility2, _node$readonly2, _node$static2, _node$
  32. line length 638 characters (raw pass, confidence 0.50)

        exports2.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-
  33. info warn → info by review long-line lib/transform/babelBundle.js:49254:1

    line length 7125 characters (raw pass, confidence 0.65)

        module2.exports.ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u06
    likely benign LLM, confidence 0.93 A long Unicode ID_Start regex character class.
    Reasoning

    This is a Unicode ID_Start regular expression with escaped code point ranges, the usual form generated by regenerate-based tooling. It is data, not hidden logic.

  34. info warn → info by review long-line lib/transform/babelBundle.js:49255:1

    line length 8583 characters (raw pass, confidence 0.65)

        module2.exports.ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u
    likely benign LLM, confidence 0.93 A long Unicode ID_Continue regex character class.
    Reasoning

    This is the companion Unicode ID_Continue regex, with the same benign data-table structure as the ID_Start one.

  35. line length 738 characters (raw pass, confidence 0.50)

        var a = { c: { longName: "chrome" }, ca: { longName: "chrome_android" }, e: { longName: "edge" }, f: { longName: "firefox" }, fa: { longName: "firefox_android" }, s: { longName: "safari" }, si: { longName: "safari_ios" }, o: { longName: "opera", engine: "Blink" }, oa: { longName: "opera_android", engine: "Blink" },
  36. line length 664 characters (raw pass, confidence 0.50)

          let g = null != e2 ? e2 : {}, q = { listAllCompatibleVersions: null !== (s2 = g.listAllCompatibleVersions) && void 0 !== s2 && s2, includeDownstreamBrowsers: null !== (o2 = g.includeDownstreamBrowsers) && void 0 !== o2 && o2, widelyAvailableOnDate: null !== (f2 = g.widelyAvailableOnDate) && void 0 !== f2 ? f2 : v
  37. line length 681 characters (raw pass, confidence 0.50)

              e3.setMonth(e3.getMonth() - 2), n2 > e3 && (null != a2 ? a2 : 1787873932909) < e3.getTime() && (console.warn("[baseline-browser-mapping] The data in this module is over two months old and you are targetting a recent feature cut off date of " + n2.toISOString().slice(0, 10) + ". To ensure accurate Baseline dat
  38. line length 2949 characters (mostly string/comment) (raw pass, confidence 0.39)

        module2.exports = { "0": "116", "1": "117", "2": "118", "3": "119", "4": "120", "5": "121", "6": "122", "7": "123", "8": "124", "9": "125", A: "10", B: "11", C: "12", D: "7", E: "8", F: "9", G: "15", H: "80", I: "151", J: "4", K: "27", L: "6", M: "13", N: "14", O: "16", P: "17", Q: "18", R: "79", S: "81", T: "83", 
  39. info warn → info by review long-line lib/transform/babelBundle.js:53869:1

    line length 31391 characters (raw pass, confidence 0.65)

        module2.exports = { A: { A: { L: 0, D: 0, E: 0, F: 0, A: 0, B: 0.266336, AD: 0 }, B: "ms", C: ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "
    likely benign LLM, confidence 0.90 A very large browser-support data object from caniuse-lite.
    Reasoning

    The line is a large caniuse-lite browser compatibility dataset serialized as one JavaScript object literal. Its length comes from data, not code that runs hidden behaviour.

  40. line length 19244 characters (mostly string/comment) (raw pass, confidence 0.39)

        module2.exports = { "0": "_I _IB", "1": "_d ZD", "2": "_qS _uI", "3": "_4 _e", "4": "J jB", "5": "B C", "6": "_Y _RF", "7": "_vS _qI", "8": "_BE _AB", "9": "gD _AB", A: "A B", B: "D A", C: "FE GE", D: "_DE _aP", E: "_PC AD", F: "J _U", G: "_FD _rS", H: "_NC _JP", I: "_v _UB", J: "_YH _tI", K: "_H _tI", L: "FD GD", 
  41. info warn → info by review dynamic-import lib/transform/babelBundle.js:54747:23

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            }
            var queries = require(require.resolve(name, { paths: [".", ctx.path] }));
            if (typeof queries === "object" && queries !== null && queries.__esModule) {
              queries = queries.default;
    likely benign LLM, confidence 0.85 Browserslist resolving and requiring a query module via require.resolve.
    Reasoning

    This is browserslist's standard config loader, which requires a module path resolved via require.resolve from user-configured paths. The non-literal specifier is expected for plugin and query resolution, and it stays within the package's own resolution.

  42. info warn → info by review dynamic-import lib/transform/babelBundle.js:54767:21

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

            }
            var stats = require(
              // Use forward slashes for module paths, also on Windows.
              require.resolve(path.posix.join(name, "browserslist-stats.json"), {
    likely benign LLM, confidence 0.85 Browserslist loading its browserslist-stats.json data file.
    Reasoning

    This is browserslist loading its browserslist-stats.json through require.resolve with a posix-joined path. It is ordinary data loading with a comment explaining the path handling.

  43. info warn → info by review dynamic-import lib/transform/babelBundle.js:54817:26

    `require` called with a non-literal specifier (ast pass, confidence 0.80)

              try {
                compressed = require("caniuse-lite/data/regions/" + code + ".js");
              } catch (e) {
                throw new BrowserslistError("Unknown region name `" + code + "`.");
    likely benign LLM, confidence 0.85 Browserslist requiring a caniuse-lite region data file by name.
    Reasoning

    The require concatenates a region code onto a caniuse-lite data path, inside a try block that rethrows a BrowserslistError. This is a lookup of bundled static data, not code loading from the network or a payload.

  44. info warn → info by review dynamic-import lib/transform/babelBundle.js:54836:24

    `require` called with a non-literal specifier (ast pass, confidence 0.80)

            try {
              compressed = require("caniuse-lite/data/features/" + name + ".js");
            } catch (e) {
              throw new BrowserslistError("Unknown feature name `" + name + "`.");
    likely benign LLM, confidence 0.85 Browserslist requiring a caniuse-lite feature data file by name.
    Reasoning

    This matches the region lookup: it requires a caniuse-lite feature data file by name with error handling, which is standard browserslist behaviour.

  45. info warn → info by review dynamic-execution lib/transform/babelBundle.js:60803:40

    `atob` decodes a base64 value at runtime — common step before dynamic fetch or eval (ast pass, confidence 0.75)

        function decodeBase64WithAtob(base64) {
          return decodeURIComponent(escape(atob(base64)));
        }
        function stripComment(sm) {
    likely benign LLM, confidence 0.80 A helper decoding base64 with atob, likely for inline source maps.
    Reasoning

    decodeBase64WithAtob is a helper that turns base64 into a string for inline source-map decoding, a common utility in Babel and source-map-support. It decodes data locally and does not execute it or fetch anything here.

  46. info dynamic-execution lib/transform/babelBundle.js:60865:14

    `btoa` encodes a value as base64 at runtime — used in exfiltration patterns (ast pass, confidence 0.55)

          var json = this.toJSON();
          return btoa(unescape(encodeURIComponent(json)));
        }
        Converter.prototype.toURI = function() {
  47. info warn → info by review dynamic-import lib/transform/babelBundle.js:62117:14

    dynamic `import(...)` with a non-literal specifier (ast pass, confidence 0.65)

        module2.exports = function import_(filepath) {
          return import(filepath);
        };
      }
    likely benign LLM, confidence 0.80 A helper wrapping dynamic import() for loading a module by file path.
    Reasoning

    A dynamic import helper that takes a filepath argument is a standard way to load user or config modules in a Node tool. The snippet shows no decoding, network access, or obfuscation.

  48. line length 529 characters (raw pass, confidence 0.50)

              if (parentParentPath.node.type === "AssignmentExpression" && parentParentPath.node.left === parentPath.node || parentParentPath.node.type === "UpdateExpression" || parentParentPath.node.type === "RestElement" || parentParentPath.node.type === "ArrayPattern" || parentParentPath.node.type === "ObjectProperty" &
  49. line length 712 characters (raw pass, confidence 0.50)

              path.replaceWithMultiple([_core.types.variableDeclaration("let", [_core.types.variableDeclarator(_core.types.cloneNode(classOuterBindingLocal)), _core.types.variableDeclarator(classOuterBindingDelegateLocal)]), _core.types.blockStatement([_core.types.variableDeclaration("let", [_core.types.variableDeclarator(
  50. line length 737 characters (raw pass, confidence 0.50)

              acc.push(_core.types.assignmentExpression("=", _core.types.cloneNode(descriptor), _core.types.callExpression(state.addHelper("applyDecoratedDescriptor"), [_core.types.cloneNode(target), _core.types.cloneNode(property), _core.types.arrayExpression(decorators.map((dec) => _core.types.cloneNode(dec.expression)))
  51. info warn → info by review dynamic-import lib/transform/babelBundle.js:72469:52

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

          ...plugins,
          ...pluginsEpilogue.map(([name, options]) => [require(name), options])
        ],
        compact: false,
    likely benign LLM, confidence 0.80 Loads Babel plugins by name from a configuration list.
    Reasoning

    The require() specifier comes from a configured list of Babel plugin names, which is ordinary plugin loading. Nothing in the snippet decodes or hides the name.

  52. info warn → info by review long-line lib/transform/esmLoader.js:2302:1

    line length 7125 characters (raw pass, confidence 0.65)

        module2.exports.ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u06
    dismissed LLM, confidence 0.92 A generated Unicode ID_Start regex table on one long line.
    Reasoning

    A very long line holding a regex built from Unicode ID_Start code point ranges is a generated lookup table. This is a classic raw-pass false positive from minified or generated data.

  53. info warn → info by review long-line lib/transform/esmLoader.js:2303:1

    line length 8583 characters (raw pass, confidence 0.65)

        module2.exports.ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u
    dismissed LLM, confidence 0.92 A generated Unicode ID_Continue regex table on one long line.
    Reasoning

    This is the companion generated ID_Continue Unicode regex table. Its length reflects the data it encodes, not hidden behaviour.

  54. info warn → info by review dynamic-import lib/transform/esmLoader.js:7880:30

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

      process.env.BROWSERSLIST_IGNORE_OLD_DATA = "true";
      const { babelTransform } = require((0, import_package2.libPath)("transform", "babelBundle"));
      const babelResult = babelTransform(originalCode, filename, !!moduleUrl, pluginsEpilogue, useDefineForClassFields, jsx);
      if (!babelResult?.code)
    likely benign LLM, confidence 0.80 Requires the bundled babel transform module through an internal path helper.
    Reasoning

    The require targets a path built from a fixed library path helper with constant segments ('transform', 'babelBundle'). This is an internal module load, not an attacker-controlled specifier.

  55. info critical → info by review dynamic-execution lib/transform/esmLoader.js:7897:29

    `eval` called with a non-literal expression (ast pass, confidence 0.90)

        const fileName = import_url2.default.pathToFileURL(file);
        const esmImport = () => eval(`import(${JSON.stringify(fileName)})`);
        if (loaderChannel) {
    likely benign LLM, confidence 0.70 Uses eval to issue a dynamic import() of a local file URL.
    Reasoning

    eval is used to build an import() call so the loader escapes transpilation to require, a known pattern in test runners. The interpolated value is a local file URL passed through JSON.stringify, not network or decoded data. The eval is unusual and warrants a note, but the evidence points to a legitimate loader.

  56. info critical → info by review dynamic-execution lib/transform/esmLoader.js:7899:13

    `eval` called with a non-literal expression (ast pass, confidence 0.90)

        if (loaderChannel) {
          await eval(`import(${JSON.stringify(fileName + ".esm.preflight")})`).catch((error) => debugTest("Failed to load preflight for " + file + ", source maps may be missing for errors thrown during loading.", error)).finally(nextTask);
        }
        return await esmImport().finally(nextTask);
    likely benign LLM, confidence 0.70 Uses eval to dynamically import an optional '.esm.preflight' companion file.
    Reasoning

    This is the same eval-wrapped import() pattern, here loading an optional preflight module next to the source file. The path comes from local file names and errors are caught, consistent with source-map support rather than a dropper.

  57. info warn → info by review dynamic-import lib/transform/esmLoader.js:7903:18

    `require` called with a non-literal specifier (ast pass, confidence 0.60)

      }
      const result = require(file);
      const depsCollector = currentFileDepsCollector();
      if (depsCollector) {
    likely benign LLM, confidence 0.80 Requires a user file during loading and collects its dependencies.
    Reasoning

    The require loads the file being tested or configured by the tool, followed by dependency collection. Loading the user's own config or test file is the expected behaviour of this tool.

  58. info whitespace-anomaly lib/worker/workerProcessEntry.js:9:1

    file mixes tab and space indentation (1 tab-indented and 1716 space-indented lines) (raw pass, confidence 0.40)

    var __copyProps = (to, from, except, desc) => {
      if (from && typeof from === "object" || typeof from === "function") {
        for (let key of __getOwnPropNames(from))
          if (!__hasOwnProp.call(to, key) && key !== except)
  59. line length 833 characters (raw pass, confidence 0.50)

        const snapshotPath = template.replace(/\{(.)?testDir\}/g, "$1" + this.project.testDir).replace(/\{(.)?snapshotDir\}/g, "$1" + this.project.snapshotDir).replace(/\{(.)?snapshotSuffix\}/g, this.snapshotSuffix ? "$1" + this.snapshotSuffix : "").replace(/\{(.)?testFileDir\}/g, "$1" + parsedRelativeTestFilePath.dir).rep
  60. info long-line types/test.d.ts:7632:1

    line length 560 characters (raw pass, confidence 0.50)

      video: VideoMode | /** deprecated */ 'retry-with-video' | { mode: VideoMode, size?: ViewportSize, fps?: number, show?: { actions?: { duration?: number, position?: 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right', /** @deprecated Use `style.title` instead. */ fontSize?: number, cursor?: 'no

Reproduce This Scan

Run disclude locally to verify. These commands scan the published file; the "new in this release" marks come from comparing it with the previous release's file, which they don't repeat. Add --format sarif for SARIF output. Add --llm (with an API key in the environment) to include the LLM review.

cargo install disclude --version 4.3.0
curl -fsSL -o playwright-1.65.0-alpha-2026-10-24.tgz https://registry.npmjs.org/playwright/-/playwright-1.65.0-alpha-2026-10-24.tgz
printf '%s  %s\n' 8ead52b6ade83f08ef431e9e5bc15a00e1573c74dd800c999d62cfd924db7665 playwright-1.65.0-alpha-2026-10-24.tgz | shasum -a 256 -c -
mkdir pkg && tar -xzf playwright-1.65.0-alpha-2026-10-24.tgz -C pkg --strip-components 1
disclude scan --untrusted --severity info pkg