mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-10-26 19:15:09 +00:00
Fix TypeError in breadcrumbs-overflow when logo item is missing (#27414)
This commit is contained in:
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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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"],
|
||||
|
||||
Reference in new issue
Block a user