Skip to content

Commit 70afe37

Browse files
committed
test(mdviewer): add tests for link click opening in default browser
Verify that clicking a markdown link in reader mode and clicking the URL in the link popover in edit mode both call NativeApp.openURLInDefaultBrowser with the expected URL. Restore original function in afterAll to guard against individual test failures.
1 parent f3d0bfa commit 70afe37

2 files changed

Lines changed: 79 additions & 2 deletions

File tree

src-mdviewer/to-create-tests.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
- [ ] Format bar appears on text selection (visual — needs real mouse interaction)
3636
- [x] Link popover edit URL via popover syncs to CM
3737
- [x] Link popover remove link via popover syncs to CM
38-
- [ ] Link popover URL opens in default browser (not Electron window)
38+
- [x] Link popover URL opens in default browser (not Electron window)
3939
- [ ] Escape in lang picker only dismisses picker, refocuses editor
4040

4141
## Empty Line Placeholder

test/spec/md-editor-integ-test.js

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ define(function (require, exports, module) {
2828
const mdTestFolder = SpecRunnerUtils.getTestPath("/spec/LiveDevelopment-Markdown-test-files");
2929

3030
let testWindow, brackets, CommandManager, Commands, EditorManager, WorkspaceManager,
31-
LiveDevMultiBrowser;
31+
LiveDevMultiBrowser, NativeApp;
3232

3333
function _getMdPreviewIFrame() {
3434
return testWindow.document.getElementById("panel-md-preview-frame");
@@ -244,6 +244,7 @@ define(function (require, exports, module) {
244244
EditorManager = brackets.test.EditorManager;
245245
WorkspaceManager = brackets.test.WorkspaceManager;
246246
LiveDevMultiBrowser = brackets.test.LiveDevMultiBrowser;
247+
NativeApp = brackets.test.NativeApp;
247248

248249
await SpecRunnerUtils.loadProjectInTestWindow(testFolder);
249250
await SpecRunnerUtils.deletePathAsync(testFolder + "/.phcode.json", true);
@@ -1238,6 +1239,16 @@ define(function (require, exports, module) {
12381239

12391240
describe("Links & Format Bar", function () {
12401241

1242+
let _originalOpenURL;
1243+
1244+
beforeAll(function () {
1245+
_originalOpenURL = NativeApp.openURLInDefaultBrowser;
1246+
});
1247+
1248+
afterAll(function () {
1249+
NativeApp.openURLInDefaultBrowser = _originalOpenURL;
1250+
});
1251+
12411252
async function _openMdFile(fileName) {
12421253
await awaitsForDone(SpecRunnerUtils.openProjectFiles([fileName]),
12431254
"open " + fileName);
@@ -1440,6 +1451,72 @@ define(function (require, exports, module) {
14401451
await awaitsForDone(CommandManager.execute(Commands.FILE_CLOSE, { _forceClose: true }),
14411452
"force close doc3.md");
14421453
}, 15000);
1454+
1455+
it("should clicking link in reader mode call openURLInDefaultBrowser", async function () {
1456+
await _openMdFile("doc2.md");
1457+
await _enterReaderMode();
1458+
1459+
let capturedURL = null;
1460+
NativeApp.openURLInDefaultBrowser = function (url) {
1461+
capturedURL = url;
1462+
};
1463+
1464+
const mdDoc = _getMdIFrameDoc();
1465+
const link = mdDoc.querySelector('#viewer-content a[href*="test-link-doc2"]');
1466+
expect(link).not.toBeNull();
1467+
link.click();
1468+
1469+
await awaitsFor(() => capturedURL !== null,
1470+
"openURLInDefaultBrowser to be called");
1471+
expect(capturedURL).toContain("test-link-doc2.example.com");
1472+
1473+
await awaitsForDone(CommandManager.execute(Commands.FILE_CLOSE, { _forceClose: true }),
1474+
"force close doc2.md");
1475+
}, 10000);
1476+
1477+
it("should clicking link in edit mode popover call openURLInDefaultBrowser", async function () {
1478+
await _openMdFile("doc2.md");
1479+
await _enterEditMode();
1480+
await _focusMdContent();
1481+
1482+
let capturedURL = null;
1483+
NativeApp.openURLInDefaultBrowser = function (url) {
1484+
capturedURL = url;
1485+
};
1486+
1487+
const mdDoc = _getMdIFrameDoc();
1488+
const content = mdDoc.getElementById("viewer-content");
1489+
const link = content.querySelector("a[href*='test-link-doc2']");
1490+
expect(link).not.toBeNull();
1491+
1492+
// Place cursor in link to trigger popover
1493+
const range = mdDoc.createRange();
1494+
range.selectNodeContents(link);
1495+
range.collapse(true);
1496+
_getMdIFrameWin().getSelection().removeAllRanges();
1497+
_getMdIFrameWin().getSelection().addRange(range);
1498+
content.dispatchEvent(new KeyboardEvent("keyup", {
1499+
key: "ArrowRight", code: "ArrowRight", bubbles: true
1500+
}));
1501+
1502+
await awaitsFor(() => {
1503+
const popover = mdDoc.getElementById("link-popover");
1504+
return popover && popover.classList.contains("visible");
1505+
}, "link popover to appear");
1506+
1507+
// Click the URL link in the popover
1508+
const popover = mdDoc.getElementById("link-popover");
1509+
const popoverLink = popover.querySelector(".link-popover-url");
1510+
expect(popoverLink).not.toBeNull();
1511+
popoverLink.click();
1512+
1513+
await awaitsFor(() => capturedURL !== null,
1514+
"openURLInDefaultBrowser to be called from popover");
1515+
expect(capturedURL).toContain("test-link-doc2.example.com");
1516+
1517+
await awaitsForDone(CommandManager.execute(Commands.FILE_CLOSE, { _forceClose: true }),
1518+
"force close doc2.md");
1519+
}, 15000);
14431520
});
14441521

14451522
describe("Empty Line Placeholder", function () {

0 commit comments

Comments
 (0)