Fix TypeError in breadcrumbs-overflow when logo item is missing (#27414)

This commit is contained in:
Kanhaiya76618 authored and GitHub committed 2026-09-25 14:20:30 -06:00
1 parent b4488dc4bf
commit c008bedaef
3 files changed
+75 -2

No files matched your search

@@ -18,7 +18,14 @@ export default function computeBreadcrumbs() {
document.querySelectorAll(`[data-type="breadcrumb-item"]`),
);
const breadcrumbsOverflow = generateOverflowButton().querySelector("button");
const overflowButton = generateOverflowButton();
if (!overflowButton) {
return;
}
const breadcrumbsOverflow = overflowButton.querySelector("button");
if (!breadcrumbsOverflow) {
return;
}
while (breadcrumbsBarOverflows()) {
const item = breadcrumbs.shift();
@@ -66,6 +73,9 @@ export default function computeBreadcrumbs() {
function breadcrumbsBarOverflows() {
const breadcrumbsBar = document.querySelector("#breadcrumbBar");
if (!breadcrumbsBar) {
return false;
}
return breadcrumbsBar.scrollWidth > breadcrumbsBar.offsetWidth;
}
@@ -80,6 +90,9 @@ function generateOverflowButton() {
// Generate an overflow menu to store breadcrumbs
const logo = document.querySelector(".jenkins-breadcrumbs__list-item");
if (!logo) {
return null;
}
const element =
createElementFromHtml(`<li class="jenkins-breadcrumbs__list-item"><button class="jenkins-button jenkins-button--tertiary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<circle cx="256" cy="256" r="45" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"/>
@@ -96,7 +109,7 @@ function removeOverflowButton() {
".jenkins-breadcrumbs__list-item .jenkins-button",
);
if (breadcrumbsOverflow) {
if (breadcrumbsOverflow && breadcrumbsOverflow.parentNode) {
breadcrumbsOverflow.parentNode.remove();
}
}
+51
View File
@@ -0,0 +1,51 @@
import { beforeEach, describe, expect, it } from "vitest";
import computeBreadcrumbs from "@/components/header/breadcrumbs-overflow";
describe("computeBreadcrumbs", () => {
beforeEach(() => {
document.body.innerHTML = "";
});
it("does not throw when breadcrumbs bar is absent", () => {
document.body.innerHTML = "<div></div>";
expect(() => computeBreadcrumbs()).not.toThrow();
});
it("does not throw when breadcrumb item is absent even if bar exists", () => {
document.body.innerHTML = '<div id="breadcrumbBar"></div>';
expect(() => computeBreadcrumbs()).not.toThrow();
});
it("does not throw when breadcrumb item is absent during overflow", () => {
document.body.innerHTML = '<div id="breadcrumbBar"></div>';
const bar = document.querySelector("#breadcrumbBar");
Object.defineProperty(bar, "scrollWidth", {
configurable: true,
get: () => 500,
});
Object.defineProperty(bar, "offsetWidth", {
configurable: true,
get: () => 300,
});
expect(() => computeBreadcrumbs()).not.toThrow();
});
it("removes overflow button when breadcrumbs bar does not overflow", () => {
document.body.innerHTML = `
<div id="breadcrumbBar">
<ol class="jenkins-breadcrumbs">
<li class="jenkins-breadcrumbs__list-item"><a href="/">Dashboard</a></li>
<li class="jenkins-breadcrumbs__list-item"><button class="jenkins-button">...</button></li>
</ol>
</div>
`;
computeBreadcrumbs();
const overflowBtn = document.querySelector(
".jenkins-breadcrumbs__list-item .jenkins-button",
);
expect(overflowBtn).toBeNull();
});
});
+9
View File
@@ -1,6 +1,15 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig } from "vitest/config";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "src/main/js"),
},
},
test: {
environment: "jsdom",
include: ["src/test/js/**/*.test.js"],