Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test runs only with pattern: os != 'android'
- Manifest: browser/components/aiwindow/models/tests/xpcshell/xpcshell.toml
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
const { getOpenTabs } = ChromeUtils.importESModule(
"moz-src:///browser/components/aiwindow/models/Tools.sys.mjs"
);
const { sinon } = ChromeUtils.importESModule(
);
function createFakeTab(url, title, lastAccessed) {
return {
linkedBrowser: {
currentURI: {
spec: url,
},
},
label: title,
lastAccessed,
};
}
function createFakeWindow(tabs, closed = false, isAIWindow = true) {
return {
closed,
gBrowser: {
tabs,
},
document: {
documentElement: {
hasAttribute: attr => attr === "ai-window" && isAIWindow,
},
},
};
}
function setupPageDataServiceMock(sandbox, descriptionMap = {}) {
const PageDataService = ChromeUtils.importESModule(
"moz-src:///browser/components/pagedata/PageDataService.sys.mjs"
).PageDataService;
sandbox.stub(PageDataService, "getCached").callsFake(url => {
if (url in descriptionMap) {
return { description: descriptionMap[url] };
}
return null;
});
sandbox.stub(PageDataService, "fetchPageData").callsFake(async url => {
if (url in descriptionMap) {
return { description: descriptionMap[url] };
}
return null;
});
}
add_task(async function test_getOpenTabs_basic() {
const BrowserWindowTracker = ChromeUtils.importESModule(
"resource:///modules/BrowserWindowTracker.sys.mjs"
).BrowserWindowTracker;
const sb = sinon.createSandbox();
try {
const fakeWindow = createFakeWindow([
]);
sb.stub(BrowserWindowTracker, "orderedWindows").get(() => [fakeWindow]);
setupPageDataServiceMock(sb, {
});
const tabs = await getOpenTabs();
Assert.equal(tabs.length, 3, "Should return all 3 tabs");
Assert.equal(tabs[0].title, "Firefox", "Title should match");
Assert.equal(
tabs[0].description,
"Firefox browser homepage",
"Description should be fetched"
);
Assert.equal(
tabs[1].description,
"Mozilla organization site",
"Description should be fetched"
);
Assert.equal(
tabs[2].description,
"",
"Description should be empty when not available"
);
} finally {
sb.restore();
}
});
add_task(async function test_getOpenTabs_filters_about_urls() {
const BrowserWindowTracker = ChromeUtils.importESModule(
"resource:///modules/BrowserWindowTracker.sys.mjs"
).BrowserWindowTracker;
const sb = sinon.createSandbox();
try {
const fakeWindow = createFakeWindow([
createFakeTab("about:preferences", "Preferences", 2000),
createFakeTab("about:config", "Config", 3000),
createFakeTab("about:blank", "Blank", 5000),
]);
sb.stub(BrowserWindowTracker, "orderedWindows").get(() => [fakeWindow]);
setupPageDataServiceMock(sb);
const tabs = await getOpenTabs();
Assert.equal(
tabs.length,
2,
"Should only return non-about: tabs (filtered 3)"
);
Assert.equal(
tabs[0].url,
"Should return mozilla.org"
);
Assert.ok(
!tabs.some(t => t.url.startsWith("about:")),
"No about: URLs in results"
);
} finally {
sb.restore();
}
});
add_task(async function test_getOpenTabs_pagination() {
const BrowserWindowTracker = ChromeUtils.importESModule(
"resource:///modules/BrowserWindowTracker.sys.mjs"
).BrowserWindowTracker;
const sb = sinon.createSandbox();
try {
const tabs = [];
for (let i = 0; i < 20; i++) {
tabs.push(
);
}
const fakeWindow = createFakeWindow(tabs);
sb.stub(BrowserWindowTracker, "orderedWindows").get(() => [fakeWindow]);
setupPageDataServiceMock(sb);
// Test default limit
const defaultResult = await getOpenTabs();
Assert.equal(defaultResult.length, 15, "Should default to 15 tabs");
Assert.equal(
defaultResult[0].url,
"First tab should be most recent"
);
// Test custom limit
const customResult = await getOpenTabs(10);
Assert.equal(customResult.length, 10, "Should return at most 10 tabs");
Assert.equal(
customResult[9].url,
"Last tab should be 10th most recent"
);
} finally {
sb.restore();
}
});
add_task(async function test_getOpenTabs_filters_non_ai_windows() {
const BrowserWindowTracker = ChromeUtils.importESModule(
"resource:///modules/BrowserWindowTracker.sys.mjs"
).BrowserWindowTracker;
const sb = sinon.createSandbox();
try {
const aiWindow = createFakeWindow(
[
],
false,
true
);
const classicWindow = createFakeWindow(
[
],
false,
false
);
sb.stub(BrowserWindowTracker, "orderedWindows").get(() => [
classicWindow,
aiWindow,
]);
setupPageDataServiceMock(sb);
const tabs = await getOpenTabs();
Assert.equal(
tabs.length,
2,
"Should only return tabs from AI Windows (filtered 2 classic tabs)"
);
Assert.ok(
!tabs.some(t => t.url.includes("classic")),
"No classic window tabs in results"
);
} finally {
sb.restore();
}
});
add_task(async function test_getOpenTabs_return_structure() {
const BrowserWindowTracker = ChromeUtils.importESModule(
"resource:///modules/BrowserWindowTracker.sys.mjs"
).BrowserWindowTracker;
const sb = sinon.createSandbox();
try {
const fakeWindow = createFakeWindow([
]);
sb.stub(BrowserWindowTracker, "orderedWindows").get(() => [fakeWindow]);
setupPageDataServiceMock(sb, {
});
const tabs = await getOpenTabs();
Assert.equal(tabs.length, 1, "Should return one tab");
const tab = tabs[0];
Assert.ok("url" in tab, "Tab should have url property");
Assert.ok("title" in tab, "Tab should have title property");
Assert.ok("description" in tab, "Tab should have description property");
Assert.ok("lastAccessed" in tab, "Tab should have lastAccessed property");
Assert.equal(typeof tab.url, "string", "url should be a string");
Assert.equal(typeof tab.title, "string", "title should be a string");
Assert.equal(
typeof tab.description,
"string",
"description should be a string"
);
Assert.equal(
typeof tab.lastAccessed,
"number",
"lastAccessed should be a number"
);
Assert.equal(tab.title, "Test Page", "title value correct");
Assert.equal(
tab.description,
"A test page description",
"description should be fetched from PageDataService"
);
Assert.equal(tab.lastAccessed, 1000, "lastAccessed value correct");
} finally {
sb.restore();
}
});