зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
acfb3e797d
|
@ -58,11 +58,14 @@ browser/extensions/formautofill/phonenumberutils/PhoneNumberMetaData.jsm
|
|||
# Ignore devtools debugger files which aren't intended for linting, and also
|
||||
# aren't included in any .eslintignore or .prettierignore file.
|
||||
# See https://github.com/firefox-devtools/debugger/blob/master/package.json#L24
|
||||
devtools/client/debugger/bin/
|
||||
devtools/client/debugger/configs/
|
||||
devtools/client/debugger/dist/
|
||||
devtools/client/debugger/images/
|
||||
devtools/client/debugger/test/
|
||||
devtools/client/debugger/packages/
|
||||
devtools/client/debugger/test/mochitest/examples/
|
||||
devtools/client/debugger/index.html
|
||||
devtools/client/debugger/webpack.config.js
|
||||
|
||||
# Ignore devtools preferences files
|
||||
devtools/client/preferences/
|
||||
|
|
11
.eslintrc.js
11
.eslintrc.js
|
@ -50,12 +50,19 @@ const ignorePatterns = [
|
|||
.split("\n"),
|
||||
...fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, "devtools", "client", "debugger", ".eslintignore")
|
||||
path.join(
|
||||
__dirname,
|
||||
"devtools",
|
||||
"client",
|
||||
"debugger",
|
||||
"src",
|
||||
".eslintignore"
|
||||
)
|
||||
)
|
||||
.toString("utf-8")
|
||||
.split("\n")
|
||||
.filter(p => p && !p.startsWith("#"))
|
||||
.map(p => `devtools/client/debugger/${p}`),
|
||||
.map(p => `devtools/client/debugger/src/${p}`),
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -51,7 +51,7 @@ static const gchar* getActionNameCB(AtkAction* aAction, gint aActionIndex) {
|
|||
AtkObject* atkObject = ATK_OBJECT(aAction);
|
||||
nsAutoString autoStr;
|
||||
if (Accessible* acc = GetInternalObj(atkObject)) {
|
||||
acc->ActionDescriptionAt(aActionIndex, autoStr);
|
||||
acc->ActionNameAt(aActionIndex, autoStr);
|
||||
return AccessibleWrap::ReturnString(autoStr);
|
||||
}
|
||||
|
||||
|
|
|
@ -1072,7 +1072,7 @@ TextLeafPoint TextLeafPoint::FindTextAttrsStart(
|
|||
RefPtr<const AccAttributes> attrs =
|
||||
isRemote ? point.mAcc->AsRemote()->GetCachedTextAttributes()
|
||||
: point.GetTextAttributesLocalAcc(aIncludeDefaults);
|
||||
if (!attrs->Equal(lastAttrs)) {
|
||||
if (attrs && lastAttrs && !attrs->Equal(lastAttrs)) {
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
@ -1087,7 +1087,7 @@ TextLeafPoint TextLeafPoint::FindTextAttrsStart(
|
|||
RefPtr<const AccAttributes> attrs =
|
||||
isRemote ? point.mAcc->AsRemote()->GetCachedTextAttributes()
|
||||
: point.GetTextAttributesLocalAcc(aIncludeDefaults);
|
||||
if (!attrs->Equal(lastAttrs)) {
|
||||
if (attrs && lastAttrs && !attrs->Equal(lastAttrs)) {
|
||||
// The attributes change here. If we're moving forward, we want to
|
||||
// return this point. If we're moving backward, we've now moved before
|
||||
// the start of the attrs run containing the origin, so return the last
|
||||
|
|
|
@ -153,9 +153,14 @@ MsaaDocAccessible::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue) {
|
|||
HRESULT hr = MsaaAccessible::get_accValue(aVarChild, aValue);
|
||||
if (FAILED(hr) || *aValue || aVarChild.lVal != CHILDID_SELF) return hr;
|
||||
|
||||
DocAccessible* docAcc = DocAcc();
|
||||
// MsaaAccessible::get_accValue should have failed (and thus we should have
|
||||
// returned early) if the Accessible is dead.
|
||||
MOZ_ASSERT(mAcc);
|
||||
if (mAcc->IsRemote()) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
DocAccessible* docAcc = DocAcc();
|
||||
// This is not remote, so it must be a local DocAccessible.
|
||||
MOZ_ASSERT(docAcc);
|
||||
// If document is being used to create a widget, don't use the URL hack
|
||||
roles::Role role = docAcc->Role();
|
||||
|
|
|
@ -1528,7 +1528,7 @@ pref("browser.newtabpage.activity-stream.discoverystream.readTime.enabled", true
|
|||
pref("browser.newtabpage.activity-stream.discoverystream.newSponsoredLabel.enabled", false);
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.essentialReadsHeader.enabled", false);
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.editorsPicksHeader.enabled", false);
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.spoc-positions", "2,4,11,20");
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.spoc-positions", "1,5,7,11,18,20");
|
||||
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint", "");
|
||||
pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint-query", "");
|
||||
|
@ -2069,6 +2069,8 @@ pref("extensions.pocket.loggedOutVariant", "control");
|
|||
pref("extensions.pocket.refresh.layout.enabled", false);
|
||||
// Just for the new Pocket panels, enables the email signup button.
|
||||
pref("extensions.pocket.refresh.emailButton.enabled", false);
|
||||
// Hides the recently saved section in the home panel.
|
||||
pref("extensions.pocket.refresh.hideRecentSaves.enabled", false);
|
||||
|
||||
pref("signon.management.page.fileImport.enabled", false);
|
||||
|
||||
|
|
|
@ -2022,11 +2022,13 @@ button {
|
|||
text-decoration: none;
|
||||
background-color: #ECECEE;
|
||||
}
|
||||
.stp_article_list .stp_article_list_thumb {
|
||||
.stp_article_list .stp_article_list_thumb,
|
||||
.stp_article_list .stp_article_list_thumb_placeholder {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
margin-inline-end: 8px;
|
||||
background-color: #ECECEE;
|
||||
}
|
||||
.stp_article_list .stp_article_list_header {
|
||||
font-style: normal;
|
||||
|
@ -2034,7 +2036,7 @@ button {
|
|||
font-size: 0.85em;
|
||||
line-height: 1.27em;
|
||||
color: #15141A;
|
||||
margin: 4px 0px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
.stp_article_list .stp_article_list_publisher {
|
||||
font-style: normal;
|
||||
|
@ -2042,7 +2044,7 @@ button {
|
|||
font-size: 0.85em;
|
||||
line-height: 1.27em;
|
||||
color: #52525E;
|
||||
margin: 4px 0px;
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
|
||||
.stp_header {
|
||||
|
@ -2111,6 +2113,12 @@ button {
|
|||
line-height: 1.07em;
|
||||
}
|
||||
|
||||
.stp_button_wide .stp_button {
|
||||
display: block;
|
||||
margin: 12px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body.stp_signup_body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; img-src https://img-getpocket.cdn.mozilla.net; object-src 'none'" />
|
||||
<base href="chrome://pocket/content/panels/">
|
||||
<link rel="localization" href="browser/branding/brandings.ftl" />
|
||||
<link rel="localization" href="browser/aboutPocket.ftl" />
|
||||
|
|
|
@ -10,11 +10,15 @@ function ArticleList(props) {
|
|||
{props.articles?.map(article => (
|
||||
<li className="stp_article_list_item">
|
||||
<a className="stp_article_list_link" href={article.url}>
|
||||
<img
|
||||
className="stp_article_list_thumb"
|
||||
src={article.thumbnail}
|
||||
alt={article.alt}
|
||||
/>
|
||||
{article.thumbnail ? (
|
||||
<img
|
||||
className="stp_article_list_thumb"
|
||||
src={article.thumbnail}
|
||||
alt={article.alt}
|
||||
/>
|
||||
) : (
|
||||
<div className="stp_article_list_thumb_placeholder" />
|
||||
)}
|
||||
<div className="stp_article_list_meta">
|
||||
<header className="stp_article_list_header">
|
||||
{article.title}
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.stp_article_list_thumb {
|
||||
.stp_article_list_thumb,
|
||||
.stp_article_list_thumb_placeholder {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
margin-inline-end: 8px;
|
||||
background-color: #ECECEE;
|
||||
}
|
||||
|
||||
.stp_article_list_header {
|
||||
|
@ -26,7 +28,7 @@
|
|||
font-size: 0.85em;
|
||||
line-height: 1.27em;
|
||||
color: #15141A;
|
||||
margin: 4px 0px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
.stp_article_list_publisher {
|
||||
|
@ -35,6 +37,6 @@
|
|||
font-size: 0.85em;
|
||||
line-height: 1.27em;
|
||||
color: #52525E;
|
||||
margin: 4px 0px;
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,3 +55,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stp_button_wide {
|
||||
.stp_button {
|
||||
display: block;
|
||||
margin: 12px 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,38 +2,140 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Header from "../Header/Header";
|
||||
import ArticleList from "../ArticleList/ArticleList";
|
||||
import PopularTopics from "../PopularTopics/PopularTopics";
|
||||
import Button from "../Button/Button";
|
||||
import panelMessaging from "../../messages";
|
||||
|
||||
function encodeThumbnail(rawSource) {
|
||||
return rawSource
|
||||
? `https://img-getpocket.cdn.mozilla.net/80x80/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(
|
||||
rawSource
|
||||
)}`
|
||||
: null;
|
||||
}
|
||||
|
||||
function Home(props) {
|
||||
const { articles, locale, topics, pockethost } = props;
|
||||
const { locale, topics, pockethost, hideRecentSaves } = props;
|
||||
const [{ articles, status }, setArticlesState] = useState({
|
||||
articles: [],
|
||||
// Can be success, loading, or error.
|
||||
status: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!hideRecentSaves) {
|
||||
// We don't display the loading message until instructed. This is because cache
|
||||
// loads should be fast, so using the loading message for cache just adds loading jank.
|
||||
panelMessaging.addMessageListener("PKT_loadingRecentSaves", function(
|
||||
resp
|
||||
) {
|
||||
setArticlesState({
|
||||
articles,
|
||||
status: "loading",
|
||||
});
|
||||
});
|
||||
|
||||
panelMessaging.addMessageListener("PKT_renderRecentSaves", function(
|
||||
resp
|
||||
) {
|
||||
const { data } = resp;
|
||||
|
||||
if (data.status === "error") {
|
||||
setArticlesState({
|
||||
articles: [],
|
||||
status: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setArticlesState({
|
||||
articles: data.map(item => ({
|
||||
url: item.resolved_url,
|
||||
// Using array notation because there is a key titled `1` (`images` is an object)
|
||||
thumbnail: encodeThumbnail(
|
||||
item?.top_image_url || item?.images?.["1"]?.src
|
||||
),
|
||||
alt: "thumbnail image",
|
||||
title: item.resolved_title,
|
||||
publisher: item.domain_metadata?.name,
|
||||
})),
|
||||
status: "success",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// tell back end we're ready
|
||||
panelMessaging.sendMessage("PKT_show_home");
|
||||
}, []);
|
||||
|
||||
let recentSavesSection = null;
|
||||
|
||||
if (status === "error" || hideRecentSaves) {
|
||||
recentSavesSection = (
|
||||
<h3
|
||||
className="header_medium"
|
||||
data-l10n-id="pocket-panel-home-new-user-cta"
|
||||
/>
|
||||
);
|
||||
} else if (status === "loading") {
|
||||
recentSavesSection = (
|
||||
<span data-l10n-id="pocket-panel-home-most-recent-saves-loading" />
|
||||
);
|
||||
} else if (status === "success") {
|
||||
if (articles?.length) {
|
||||
recentSavesSection = (
|
||||
<>
|
||||
<h3
|
||||
className="header_medium"
|
||||
data-l10n-id="pocket-panel-home-most-recent-saves"
|
||||
/>
|
||||
{articles.length > 3 ? (
|
||||
<>
|
||||
<ArticleList articles={articles.slice(0, 3)} />
|
||||
<span className="stp_button_wide">
|
||||
<Button style="secondary">
|
||||
<span data-l10n-id="pocket-panel-button-show-all" />
|
||||
</Button>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<ArticleList articles={articles} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
recentSavesSection = (
|
||||
<>
|
||||
<h3
|
||||
className="header_medium"
|
||||
data-l10n-id="pocket-panel-home-new-user-cta"
|
||||
/>
|
||||
<h3
|
||||
className="header_medium"
|
||||
data-l10n-id="pocket-panel-home-new-user-message"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="stp_panel_container">
|
||||
<div className="stp_panel stp_panel_home">
|
||||
<Header>
|
||||
<a>
|
||||
<span data-l10n-id="pocket-panel-header-my-list"></span>
|
||||
</a>
|
||||
<Button style="primary">
|
||||
<span data-l10n-id="pocket-panel-header-my-list" />
|
||||
</Button>
|
||||
</Header>
|
||||
<hr />
|
||||
{articles?.length ? (
|
||||
<>
|
||||
<p data-l10n-id="pocket-panel-home-most-recent-saves"></p>
|
||||
<ArticleList articles={articles} />
|
||||
<span data-l10n-id="pocket-panel-button-show-all"></span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p data-l10n-id="pocket-panel-home-new-user-cta"></p>
|
||||
<p data-l10n-id="pocket-panel-home-new-user-message"></p>
|
||||
</>
|
||||
)}
|
||||
{recentSavesSection}
|
||||
<hr />
|
||||
{pockethost && locale?.startsWith("en") && topics?.length && (
|
||||
<>
|
||||
<div>Explore popular topics:</div>
|
||||
<h3 className="header_medium">Explore popular topics:</h3>
|
||||
<PopularTopics topics={topics} pockethost={pockethost} />
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -42,6 +42,7 @@ HomeOverlay.prototype = {
|
|||
const pockethost = searchParams.get(`pockethost`) || `getpocket.com`;
|
||||
const locale = searchParams.get(`locale`) || ``;
|
||||
const layoutRefresh = searchParams.get(`layoutRefresh`) === `true`;
|
||||
const hideRecentSaves = searchParams.get(`hiderecentsaves`) === `true`;
|
||||
|
||||
if (this.active) {
|
||||
return;
|
||||
|
@ -53,13 +54,19 @@ HomeOverlay.prototype = {
|
|||
ReactDOM.render(
|
||||
<Home
|
||||
locale={locale}
|
||||
articles={[]}
|
||||
hideRecentSaves={hideRecentSaves}
|
||||
pockethost={pockethost}
|
||||
topics={[
|
||||
{ title: "Technology", topic: "technology" },
|
||||
{ title: "Self Improvement", topic: "self-improvement" },
|
||||
{ title: "Food", topic: "food" },
|
||||
{ title: "Entertainment", topic: "entertainment" },
|
||||
{ title: "Parenting", topic: "parenting" },
|
||||
{ title: "Science", topic: "science" },
|
||||
{ title: "Entertainment", topic: "entertainment" },
|
||||
{ title: "Career", topic: "career" },
|
||||
{ title: "Health", topic: "health" },
|
||||
{ title: "Travel", topic: "travel" },
|
||||
{ title: "Must-Reads", topic: "must-reads" },
|
||||
]}
|
||||
/>,
|
||||
document.querySelector(`body`)
|
||||
|
@ -104,10 +111,10 @@ HomeOverlay.prototype = {
|
|||
|
||||
// click events
|
||||
this.setupClickEvents();
|
||||
}
|
||||
|
||||
// tell back end we're ready
|
||||
pktPanelMessaging.sendMessage("PKT_show_home");
|
||||
// tell back end we're ready
|
||||
pktPanelMessaging.sendMessage("PKT_show_home");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -63,10 +63,12 @@ function ArticleList(props) {
|
|||
}, /*#__PURE__*/react.createElement("a", {
|
||||
className: "stp_article_list_link",
|
||||
href: article.url
|
||||
}, /*#__PURE__*/react.createElement("img", {
|
||||
}, article.thumbnail ? /*#__PURE__*/react.createElement("img", {
|
||||
className: "stp_article_list_thumb",
|
||||
src: article.thumbnail,
|
||||
alt: article.alt
|
||||
}) : /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_article_list_thumb_placeholder"
|
||||
}), /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_article_list_meta"
|
||||
}, /*#__PURE__*/react.createElement("header", {
|
||||
|
@ -96,45 +98,20 @@ function PopularTopics(props) {
|
|||
}
|
||||
|
||||
/* harmony default export */ const PopularTopics_PopularTopics = (PopularTopics);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/components/Home/Home.jsx
|
||||
;// CONCATENATED MODULE: ./content/panels/js/components/Button/Button.jsx
|
||||
/* 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 file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Home(props) {
|
||||
const {
|
||||
articles,
|
||||
locale,
|
||||
topics,
|
||||
pockethost
|
||||
} = props;
|
||||
return /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_panel_container"
|
||||
}, /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_panel stp_panel_home"
|
||||
}, /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement("a", null, /*#__PURE__*/react.createElement("span", {
|
||||
"data-l10n-id": "pocket-panel-header-my-list"
|
||||
}))), /*#__PURE__*/react.createElement("hr", null), articles?.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("p", {
|
||||
"data-l10n-id": "pocket-panel-home-most-recent-saves"
|
||||
}), /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
||||
articles: articles
|
||||
}), /*#__PURE__*/react.createElement("span", {
|
||||
"data-l10n-id": "pocket-panel-button-show-all"
|
||||
})) : /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("p", {
|
||||
"data-l10n-id": "pocket-panel-home-new-user-cta"
|
||||
}), /*#__PURE__*/react.createElement("p", {
|
||||
"data-l10n-id": "pocket-panel-home-new-user-message"
|
||||
})), /*#__PURE__*/react.createElement("hr", null), pockethost && locale?.startsWith("en") && topics?.length && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", null, "Explore popular topics:"), /*#__PURE__*/react.createElement(PopularTopics_PopularTopics, {
|
||||
topics: topics,
|
||||
pockethost: pockethost
|
||||
}))));
|
||||
function Button(props) {
|
||||
return /*#__PURE__*/react.createElement("a", {
|
||||
href: props.url,
|
||||
className: `stp_button${props?.style && ` stp_button_${props.style}`}`
|
||||
}, props.children);
|
||||
}
|
||||
|
||||
/* harmony default export */ const Home_Home = (Home);
|
||||
/* harmony default export */ const Button_Button = (Button);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/messages.js
|
||||
/* global RPMRemoveMessageListener:false, RPMAddMessageListener:false, RPMSendAsyncMessage:false */
|
||||
var pktPanelMessaging = {
|
||||
|
@ -189,6 +166,131 @@ var pktPanelMessaging = {
|
|||
|
||||
};
|
||||
/* harmony default export */ const messages = (pktPanelMessaging);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/components/Home/Home.jsx
|
||||
/* 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 file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function encodeThumbnail(rawSource) {
|
||||
return rawSource ? `https://img-getpocket.cdn.mozilla.net/80x80/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(rawSource)}` : null;
|
||||
}
|
||||
|
||||
function Home(props) {
|
||||
const {
|
||||
locale,
|
||||
topics,
|
||||
pockethost,
|
||||
hideRecentSaves
|
||||
} = props;
|
||||
const [{
|
||||
articles,
|
||||
status
|
||||
}, setArticlesState] = (0,react.useState)({
|
||||
articles: [],
|
||||
// Can be success, loading, or error.
|
||||
status: ""
|
||||
});
|
||||
(0,react.useEffect)(() => {
|
||||
if (!hideRecentSaves) {
|
||||
// We don't display the loading message until instructed. This is because cache
|
||||
// loads should be fast, so using the loading message for cache just adds loading jank.
|
||||
messages.addMessageListener("PKT_loadingRecentSaves", function (resp) {
|
||||
setArticlesState({
|
||||
articles,
|
||||
status: "loading"
|
||||
});
|
||||
});
|
||||
messages.addMessageListener("PKT_renderRecentSaves", function (resp) {
|
||||
const {
|
||||
data
|
||||
} = resp;
|
||||
|
||||
if (data.status === "error") {
|
||||
setArticlesState({
|
||||
articles: [],
|
||||
status: "error"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setArticlesState({
|
||||
articles: data.map(item => ({
|
||||
url: item.resolved_url,
|
||||
// Using array notation because there is a key titled `1` (`images` is an object)
|
||||
thumbnail: encodeThumbnail(item?.top_image_url || item?.images?.["1"]?.src),
|
||||
alt: "thumbnail image",
|
||||
title: item.resolved_title,
|
||||
publisher: item.domain_metadata?.name
|
||||
})),
|
||||
status: "success"
|
||||
});
|
||||
});
|
||||
} // tell back end we're ready
|
||||
|
||||
|
||||
messages.sendMessage("PKT_show_home");
|
||||
}, []);
|
||||
let recentSavesSection = null;
|
||||
|
||||
if (status === "error" || hideRecentSaves) {
|
||||
recentSavesSection = /*#__PURE__*/react.createElement("h3", {
|
||||
className: "header_medium",
|
||||
"data-l10n-id": "pocket-panel-home-new-user-cta"
|
||||
});
|
||||
} else if (status === "loading") {
|
||||
recentSavesSection = /*#__PURE__*/react.createElement("span", {
|
||||
"data-l10n-id": "pocket-panel-home-most-recent-saves-loading"
|
||||
});
|
||||
} else if (status === "success") {
|
||||
if (articles?.length) {
|
||||
recentSavesSection = /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
||||
className: "header_medium",
|
||||
"data-l10n-id": "pocket-panel-home-most-recent-saves"
|
||||
}), articles.length > 3 ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
||||
articles: articles.slice(0, 3)
|
||||
}), /*#__PURE__*/react.createElement("span", {
|
||||
className: "stp_button_wide"
|
||||
}, /*#__PURE__*/react.createElement(Button_Button, {
|
||||
style: "secondary"
|
||||
}, /*#__PURE__*/react.createElement("span", {
|
||||
"data-l10n-id": "pocket-panel-button-show-all"
|
||||
})))) : /*#__PURE__*/react.createElement(ArticleList_ArticleList, {
|
||||
articles: articles
|
||||
}));
|
||||
} else {
|
||||
recentSavesSection = /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
||||
className: "header_medium",
|
||||
"data-l10n-id": "pocket-panel-home-new-user-cta"
|
||||
}), /*#__PURE__*/react.createElement("h3", {
|
||||
className: "header_medium",
|
||||
"data-l10n-id": "pocket-panel-home-new-user-message"
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_panel_container"
|
||||
}, /*#__PURE__*/react.createElement("div", {
|
||||
className: "stp_panel stp_panel_home"
|
||||
}, /*#__PURE__*/react.createElement(Header_Header, null, /*#__PURE__*/react.createElement(Button_Button, {
|
||||
style: "primary"
|
||||
}, /*#__PURE__*/react.createElement("span", {
|
||||
"data-l10n-id": "pocket-panel-header-my-list"
|
||||
}))), /*#__PURE__*/react.createElement("hr", null), recentSavesSection, /*#__PURE__*/react.createElement("hr", null), pockethost && locale?.startsWith("en") && topics?.length && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("h3", {
|
||||
className: "header_medium"
|
||||
}, "Explore popular topics:"), /*#__PURE__*/react.createElement(PopularTopics_PopularTopics, {
|
||||
topics: topics,
|
||||
pockethost: pockethost
|
||||
}))));
|
||||
}
|
||||
|
||||
/* harmony default export */ const Home_Home = (Home);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/home/overlay.js
|
||||
/* global Handlebars:false */
|
||||
|
||||
|
@ -235,6 +337,7 @@ HomeOverlay.prototype = {
|
|||
const pockethost = searchParams.get(`pockethost`) || `getpocket.com`;
|
||||
const locale = searchParams.get(`locale`) || ``;
|
||||
const layoutRefresh = searchParams.get(`layoutRefresh`) === `true`;
|
||||
const hideRecentSaves = searchParams.get(`hiderecentsaves`) === `true`;
|
||||
|
||||
if (this.active) {
|
||||
return;
|
||||
|
@ -246,20 +349,38 @@ HomeOverlay.prototype = {
|
|||
// Create actual content
|
||||
react_dom.render( /*#__PURE__*/react.createElement(Home_Home, {
|
||||
locale: locale,
|
||||
articles: [],
|
||||
hideRecentSaves: hideRecentSaves,
|
||||
pockethost: pockethost,
|
||||
topics: [{
|
||||
title: "Technology",
|
||||
topic: "technology"
|
||||
}, {
|
||||
title: "Self Improvement",
|
||||
topic: "self-improvement"
|
||||
}, {
|
||||
title: "Food",
|
||||
topic: "food"
|
||||
}, {
|
||||
title: "Entertainment",
|
||||
topic: "entertainment"
|
||||
title: "Parenting",
|
||||
topic: "parenting"
|
||||
}, {
|
||||
title: "Science",
|
||||
topic: "science"
|
||||
}, {
|
||||
title: "Entertainment",
|
||||
topic: "entertainment"
|
||||
}, {
|
||||
title: "Career",
|
||||
topic: "career"
|
||||
}, {
|
||||
title: "Health",
|
||||
topic: "health"
|
||||
}, {
|
||||
title: "Travel",
|
||||
topic: "travel"
|
||||
}, {
|
||||
title: "Must-Reads",
|
||||
topic: "must-reads"
|
||||
}]
|
||||
}), document.querySelector(`body`));
|
||||
} else {
|
||||
|
@ -299,29 +420,14 @@ HomeOverlay.prototype = {
|
|||
} // click events
|
||||
|
||||
|
||||
this.setupClickEvents();
|
||||
} // tell back end we're ready
|
||||
this.setupClickEvents(); // tell back end we're ready
|
||||
|
||||
|
||||
messages.sendMessage("PKT_show_home");
|
||||
messages.sendMessage("PKT_show_home");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
/* harmony default export */ const overlay = (HomeOverlay);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/components/Button/Button.jsx
|
||||
/* 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 file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
function Button(props) {
|
||||
return /*#__PURE__*/react.createElement("a", {
|
||||
href: props.url,
|
||||
className: `stp_button${props?.style && ` stp_button_${props.style}`}`
|
||||
}, props.children);
|
||||
}
|
||||
|
||||
/* harmony default export */ const Button_Button = (Button);
|
||||
;// CONCATENATED MODULE: ./content/panels/js/components/Signup/Signup.jsx
|
||||
/* 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 file,
|
||||
|
|
|
@ -48,6 +48,11 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"IndexedDB",
|
||||
"resource://gre/modules/IndexedDB.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["XMLHttpRequest"]);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
|
@ -57,6 +62,31 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
false
|
||||
);
|
||||
|
||||
const DB_NAME = "SaveToPocket";
|
||||
const STORE_NAME = "pktAPI";
|
||||
const DB_VERSION = 1;
|
||||
const RECENT_SAVES_UPDATE_TIME = 5 * 60 * 1000; // 30 minutes
|
||||
|
||||
/**
|
||||
* Create a new connection to the database.
|
||||
*/
|
||||
function openDatabase() {
|
||||
return IndexedDB.open(DB_NAME, DB_VERSION, db => {
|
||||
db.createObjectStore(STORE_NAME);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache the database connection so that it is shared among multiple operations.
|
||||
*/
|
||||
let databasePromise;
|
||||
function getDatabase() {
|
||||
if (!databasePromise) {
|
||||
databasePromise = openDatabase();
|
||||
}
|
||||
return databasePromise;
|
||||
}
|
||||
|
||||
var pktApi = (function() {
|
||||
/**
|
||||
* Configuration
|
||||
|
@ -388,6 +418,7 @@ var pktApi = (function() {
|
|||
}
|
||||
data.ho2 = getSetting("test.ho2");
|
||||
|
||||
_expireRecentSavesCache();
|
||||
if (options.success) {
|
||||
options.success.apply(options, Array.apply(null, arguments));
|
||||
}
|
||||
|
@ -719,6 +750,64 @@ var pktApi = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
async function _getRecentSavesCache() {
|
||||
const db = await getDatabase();
|
||||
return db.objectStore(STORE_NAME, "readonly").get("recentSaves");
|
||||
}
|
||||
async function _setRecentSavesCache(data) {
|
||||
const db = await getDatabase();
|
||||
db.objectStore(STORE_NAME, "readwrite").put(data, "recentSaves");
|
||||
}
|
||||
// Clears the cache time, so the next get forces an update.
|
||||
async function _expireRecentSavesCache() {
|
||||
const cache = await _getRecentSavesCache();
|
||||
_setRecentSavesCache({
|
||||
...cache,
|
||||
lastUpdated: 0,
|
||||
});
|
||||
}
|
||||
|
||||
async function getRecentSavesCache() {
|
||||
// Get cache
|
||||
const cache = await _getRecentSavesCache();
|
||||
// Check age
|
||||
if (
|
||||
cache?.lastUpdated &&
|
||||
Date.now() - cache.lastUpdated < RECENT_SAVES_UPDATE_TIME
|
||||
) {
|
||||
// Return cache if it's not too old.
|
||||
return cache.list;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getRecentSaves(options = {}) {
|
||||
pktApi.retrieve(
|
||||
{ count: 4 },
|
||||
{
|
||||
success(data) {
|
||||
// Cache results
|
||||
const results = {
|
||||
lastUpdated: Date.now(),
|
||||
// We want these to show up in the same order as they saved,
|
||||
// so we need to do some work and sort.
|
||||
list: Object.values(data.list)
|
||||
.map(item => ({
|
||||
...item,
|
||||
time_added: parseInt(item.time_added),
|
||||
}))
|
||||
.sort((a, b) => b.time_added - a.time_added),
|
||||
};
|
||||
_setRecentSavesCache(results);
|
||||
options.success?.(results.list);
|
||||
},
|
||||
error(error) {
|
||||
options.error?.(error);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
@ -736,6 +825,8 @@ var pktApi = (function() {
|
|||
getSuggestedTagsForItem,
|
||||
getSuggestedTagsForURL,
|
||||
retrieve,
|
||||
getRecentSavesCache,
|
||||
getRecentSaves,
|
||||
getArticleInfo,
|
||||
getMobileDownload,
|
||||
};
|
||||
|
|
|
@ -222,7 +222,10 @@ var pktUI = (function() {
|
|||
homeVersion = "control";
|
||||
}
|
||||
const sizes = initialPanelSize.home[homeVersion];
|
||||
showPanel("about:pocket-home", sizes);
|
||||
const hideRecentSaves = NimbusFeatures.saveToPocket.getVariable(
|
||||
"hideRecentSaves"
|
||||
);
|
||||
showPanel(`about:pocket-home?hiderecentsaves=${hideRecentSaves}`, sizes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -271,7 +274,7 @@ var pktUI = (function() {
|
|||
);
|
||||
}
|
||||
|
||||
function onShowHome() {
|
||||
async function onShowHome() {
|
||||
// A successful home button click.
|
||||
pktTelemetry.sendStructuredIngestionEvent(
|
||||
pktTelemetry.createPingPayload({
|
||||
|
@ -283,6 +286,35 @@ var pktUI = (function() {
|
|||
],
|
||||
})
|
||||
);
|
||||
|
||||
if (
|
||||
NimbusFeatures.saveToPocket.getVariable("layoutRefresh") &&
|
||||
!NimbusFeatures.saveToPocket.getVariable("hideRecentSaves")
|
||||
) {
|
||||
let recentSaves = await pktApi.getRecentSavesCache();
|
||||
if (recentSaves) {
|
||||
// We have cache, so we can use those.
|
||||
pktUIMessaging.sendMessageToPanel("PKT_renderRecentSaves", recentSaves);
|
||||
} else {
|
||||
// Let the client know we're loading fresh recs.
|
||||
pktUIMessaging.sendMessageToPanel(
|
||||
"PKT_loadingRecentSaves",
|
||||
recentSaves
|
||||
);
|
||||
// We don't have cache, so fetch fresh stories.
|
||||
pktApi.getRecentSaves({
|
||||
success(data) {
|
||||
pktUIMessaging.sendMessageToPanel("PKT_renderRecentSaves", data);
|
||||
},
|
||||
error(error) {
|
||||
pktUIMessaging.sendErrorMessageToPanel(
|
||||
"PKT_renderRecentSaves",
|
||||
error
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onShowSaved() {
|
||||
|
|
|
@ -650,7 +650,7 @@
|
|||
preference="browser.urlbar.suggest.topsites"/>
|
||||
<checkbox id="enginesSuggestion" data-l10n-id="addressbar-locbar-engines-option"
|
||||
preference="browser.urlbar.suggest.engines"/>
|
||||
<hbox id="firefoxSuggestBestMatchContainer" align="center">
|
||||
<hbox id="firefoxSuggestBestMatchContainer" align="center" hidden="true">
|
||||
<checkbox id="firefoxSuggestBestMatch"
|
||||
class="tail-with-learn-more"
|
||||
data-l10n-id="addressbar-firefox-suggest-best-match-option"
|
||||
|
|
|
@ -1998,6 +1998,11 @@ var gPrivacyPane = {
|
|||
* Pass true when calling this when initializing the pane.
|
||||
*/
|
||||
_updateFirefoxSuggestSection(onInit = false) {
|
||||
// Show the best match checkbox container as appropriate.
|
||||
document.getElementById(
|
||||
"firefoxSuggestBestMatchContainer"
|
||||
).hidden = !UrlbarPrefs.get("bestMatchEnabled");
|
||||
|
||||
let container = document.getElementById("firefoxSuggestContainer");
|
||||
|
||||
if (UrlbarPrefs.get("quickSuggestEnabled")) {
|
||||
|
@ -2017,11 +2022,6 @@ var gPrivacyPane = {
|
|||
.getElementById("openSearchEnginePreferences")
|
||||
.classList.add("extraMargin");
|
||||
|
||||
// Show the best match checkbox container as appropriate.
|
||||
document.getElementById(
|
||||
"firefoxSuggestBestMatchContainer"
|
||||
).hidden = !UrlbarPrefs.get("bestMatchEnabled");
|
||||
|
||||
// Show the container.
|
||||
this._updateFirefoxSuggestInfoBox();
|
||||
container.removeAttribute("hidden");
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
UrlbarProviderQuickSuggest:
|
||||
"resource:///modules/UrlbarProviderQuickSuggest.jsm",
|
||||
UrlbarQuickSuggest: "resource:///modules/UrlbarQuickSuggest.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "QuickSuggestTestUtils", () => {
|
||||
|
@ -125,12 +126,16 @@ async function doVisibilityTest({
|
|||
}) {
|
||||
info(
|
||||
"Running visibility test: " +
|
||||
JSON.stringify({
|
||||
initialScenario,
|
||||
initialExpectedVisibility,
|
||||
newScenario,
|
||||
newExpectedVisibility,
|
||||
})
|
||||
JSON.stringify(
|
||||
{
|
||||
initialScenario,
|
||||
initialExpectedVisibility,
|
||||
newScenario,
|
||||
newExpectedVisibility,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
// Set the initial scenario.
|
||||
|
@ -499,73 +504,112 @@ add_task(async function clickLearnMore() {
|
|||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Tests the visibility of the best match checkbox when the best match feature is
|
||||
// initially disabled and is then enabled via preferences.
|
||||
add_task(async function bestMatchVisibility_falseToTrue() {
|
||||
await doBestMatchVisibilityTest(false, true);
|
||||
});
|
||||
|
||||
// Tests the visibility of the best match checkbox when the best match feature is
|
||||
// initially enabled and is then disabled via preferences.
|
||||
add_task(async function bestMatchVisibility_trueToFalse() {
|
||||
await doBestMatchVisibilityTest(true, false);
|
||||
// Tests the visibility of the best match checkbox based on the values of
|
||||
// `browser.urlbar.quicksuggest.enabled` and `browser.urlbar.bestMatch.enabled`.
|
||||
add_task(async function bestMatchVisibility() {
|
||||
for (let initialQuickSuggest of [false, true]) {
|
||||
for (let initialBestMatch of [false, true]) {
|
||||
for (let newQuickSuggest of [false, true]) {
|
||||
for (let newBestMatch of [false, true]) {
|
||||
await doBestMatchVisibilityTest({
|
||||
initialQuickSuggest,
|
||||
initialBestMatch,
|
||||
newQuickSuggest,
|
||||
newBestMatch,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Runs a test that checks the visibility of the Firefox Suggest best match
|
||||
* checkbox. It sets the best match feature pref, opens about:preferences and
|
||||
* checks the visibility of the toggle, sets the feature pref again, and checks
|
||||
* the visibility of the toggle again.
|
||||
* checkbox. It does the following:
|
||||
*
|
||||
* @param {boolean} initialEnabled
|
||||
* Whether to enable the best match feature before about:preferences is
|
||||
* opened.
|
||||
* @param {boolean} newEnabled
|
||||
* Whether to enable the best match feature after about:preferences is
|
||||
* opened.
|
||||
* 1. Sets the quick suggest and best match feature prefs
|
||||
* 2. Opens about:preferences and checks the visibility of the checkbox
|
||||
* 3. Sets the quick suggest and best match feature prefs again
|
||||
* 4. Checks the visibility of the checkbox again
|
||||
*
|
||||
* @param {boolean} initialQuickSuggest
|
||||
* The value to set for `browser.urlbar.quicksuggest.enabled` before
|
||||
* about:preferences is opened.
|
||||
* @param {boolean} initialBestMatch
|
||||
* The value to set for `browser.urlbar.bestMatch.enabled` before
|
||||
* about:preferences is opened.
|
||||
* @param {boolean} newQuickSuggest
|
||||
* The value to set for `browser.urlbar.quicksuggest.enabled` while
|
||||
* about:preferences is open.
|
||||
* @param {boolean} newBestMatch
|
||||
* The value to set for `browser.urlbar.bestMatch.enabled` while
|
||||
* about:preferences is open.
|
||||
*/
|
||||
async function doBestMatchVisibilityTest(initialEnabled, newEnabled) {
|
||||
async function doBestMatchVisibilityTest({
|
||||
initialQuickSuggest,
|
||||
initialBestMatch,
|
||||
newQuickSuggest,
|
||||
newBestMatch,
|
||||
}) {
|
||||
info(
|
||||
"Running best match visibility test: " +
|
||||
JSON.stringify({ initialEnabled, newEnabled })
|
||||
JSON.stringify(
|
||||
{
|
||||
initialQuickSuggest,
|
||||
initialBestMatch,
|
||||
newQuickSuggest,
|
||||
newBestMatch,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
// Set the initial enabled status.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.urlbar.bestMatch.enabled", initialEnabled]],
|
||||
});
|
||||
// Set the initial pref values.
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.urlbar.quicksuggest.enabled",
|
||||
initialQuickSuggest
|
||||
);
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.urlbar.bestMatch.enabled",
|
||||
initialBestMatch
|
||||
);
|
||||
await UrlbarQuickSuggest.readyPromise;
|
||||
|
||||
// Open prefs and check the initial visibility.
|
||||
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
|
||||
|
||||
let doc = gBrowser.selectedBrowser.contentDocument;
|
||||
let container = doc.getElementById(BEST_MATCH_CONTAINER_ID);
|
||||
Assert.equal(
|
||||
BrowserTestUtils.is_visible(container),
|
||||
initialEnabled,
|
||||
initialBestMatch,
|
||||
"The checkbox container has the expected initial visibility"
|
||||
);
|
||||
|
||||
// Set the new enabled status.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.urlbar.bestMatch.enabled", newEnabled]],
|
||||
});
|
||||
// Set the new pref values.
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.urlbar.quicksuggest.enabled",
|
||||
newQuickSuggest
|
||||
);
|
||||
Services.prefs.setBoolPref("browser.urlbar.bestMatch.enabled", newBestMatch);
|
||||
await UrlbarQuickSuggest.readyPromise;
|
||||
|
||||
// Check visibility again.
|
||||
Assert.equal(
|
||||
BrowserTestUtils.is_visible(container),
|
||||
newEnabled,
|
||||
"The checkbox container has the expected visibility after setting enabled status"
|
||||
newBestMatch,
|
||||
"The checkbox container has the expected visibility after setting prefs"
|
||||
);
|
||||
|
||||
// Clean up.
|
||||
gBrowser.removeCurrentTab();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
Services.prefs.clearUserPref("browser.urlbar.quicksuggest.enabled");
|
||||
Services.prefs.clearUserPref("browser.urlbar.bestMatch.enabled");
|
||||
await UrlbarQuickSuggest.readyPromise;
|
||||
}
|
||||
|
||||
// Tests the visibility of the best match checkbox container when the best match feature is
|
||||
// enabled via a Nimbus experiment before about:preferences is opened.
|
||||
// Tests the visibility of the best match checkbox when the best match feature
|
||||
// is enabled via a Nimbus experiment before about:preferences is opened.
|
||||
add_task(async function bestMatchVisibility_experiment_beforeOpen() {
|
||||
await QuickSuggestTestUtils.withExperiment({
|
||||
valueOverrides: {
|
||||
|
@ -586,8 +630,8 @@ add_task(async function bestMatchVisibility_experiment_beforeOpen() {
|
|||
});
|
||||
});
|
||||
|
||||
// Tests the visibility of the best match checkbox container when the best match feature is
|
||||
// enabled via a Nimbus experiment after about:preferences is opened.
|
||||
// Tests the visibility of the best match checkbox when the best match feature
|
||||
// is enabled via a Nimbus experiment after about:preferences is opened.
|
||||
add_task(async function bestMatchVisibility_experiment_afterOpen() {
|
||||
// Open prefs and check the initial visibility.
|
||||
await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
|
||||
|
@ -661,7 +705,8 @@ add_task(async function bestMatchToggle() {
|
|||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// Clicks the learn-more link for best match and checks the help page is opened in a new tab.
|
||||
// Clicks the learn-more link for best match and checks the help page is opened
|
||||
// in a new tab.
|
||||
add_task(async function clickBestMatchLearnMore() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.urlbar.bestMatch.enabled", true]],
|
||||
|
|
|
@ -24,10 +24,9 @@
|
|||
#include "imgIContainer.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/WidgetUtils.h"
|
||||
#include "mozilla/WidgetUtilsGtk.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
# include "nsImageToPixbuf.h"
|
||||
#endif
|
||||
#include "nsImageToPixbuf.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
|
@ -72,18 +71,6 @@ static const MimeTypeAssociation appTypes[] = {
|
|||
#define kDesktopDrawBGGSKey "draw-background"
|
||||
#define kDesktopColorGSKey "primary-color"
|
||||
|
||||
static bool IsRunningAsASnap() {
|
||||
const char* snapName = mozilla::widget::WidgetUtils::GetSnapInstanceName();
|
||||
|
||||
// return early if not set.
|
||||
if (snapName == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// snapName as defined on https://snapcraft.io/firefox
|
||||
return (strcmp(snapName, "firefox") == 0);
|
||||
}
|
||||
|
||||
nsresult nsGNOMEShellService::Init() {
|
||||
nsresult rv;
|
||||
|
||||
|
@ -200,9 +187,9 @@ nsGNOMEShellService::IsDefaultBrowser(bool aForAllTypes,
|
|||
bool* aIsDefaultBrowser) {
|
||||
*aIsDefaultBrowser = false;
|
||||
|
||||
if (IsRunningAsASnap()) {
|
||||
if (widget::IsRunningUnderSnap()) {
|
||||
const gchar* argv[] = {"xdg-settings", "check", "default-web-browser",
|
||||
"firefox.desktop", nullptr};
|
||||
(SNAP_INSTANCE_NAME ".desktop"), nullptr};
|
||||
GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL);
|
||||
gchar* output = nullptr;
|
||||
|
@ -280,9 +267,9 @@ nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) {
|
|||
"Setting the default browser for all users is not yet supported");
|
||||
#endif
|
||||
|
||||
if (IsRunningAsASnap()) {
|
||||
if (widget::IsRunningUnderSnap()) {
|
||||
const gchar* argv[] = {"xdg-settings", "set", "default-web-browser",
|
||||
"firefox.desktop", nullptr};
|
||||
(SNAP_INSTANCE_NAME ".desktop"), nullptr};
|
||||
GSpawnFlags flags = static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH |
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL);
|
||||
|
@ -370,9 +357,6 @@ nsGNOMEShellService::GetCanSetDesktopBackground(bool* aResult) {
|
|||
}
|
||||
|
||||
static nsresult WriteImage(const nsCString& aPath, imgIContainer* aImage) {
|
||||
#if !defined(MOZ_WIDGET_GTK)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#else
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(aImage);
|
||||
if (!pixbuf) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -382,7 +366,6 @@ static nsresult WriteImage(const nsCString& aPath, imgIContainer* aImage) {
|
|||
|
||||
g_object_unref(pixbuf);
|
||||
return res ? NS_OK : NS_ERROR_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -53,6 +53,7 @@ pocket-panel-home-discover-more = Discover More
|
|||
pocket-panel-home-explore-more = Explore
|
||||
|
||||
pocket-panel-home-most-recent-saves = Here are your most recent saves:
|
||||
pocket-panel-home-most-recent-saves-loading = Recent saves loading…
|
||||
pocket-panel-home-new-user-cta = Click the { -pocket-brand-name } button to save articles, videos, and links.
|
||||
pocket-panel-home-new-user-message = See your recent saves here.
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
"client/shared/*.jsm",
|
||||
"client/shared/widgets/*.jsm",
|
||||
"client/storage/VariablesView.jsm",
|
||||
"client/debugger/test/**",
|
||||
],
|
||||
rules: {
|
||||
"consistent-return": "off",
|
||||
|
@ -77,7 +78,7 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
{
|
||||
files: ["client/framework/**"],
|
||||
files: ["client/framework/**", "client/debugger/test/**"],
|
||||
rules: {
|
||||
strict: "off",
|
||||
},
|
||||
|
@ -135,7 +136,7 @@ module.exports = {
|
|||
excludedFiles: [
|
||||
// Debugger modules have a custom bundling logic which relies on relative
|
||||
// paths.
|
||||
"client/debugger/**",
|
||||
"client/debugger/src/**",
|
||||
// `client/shared/build` contains node helpers to build the debugger and
|
||||
// not devtools modules.
|
||||
"client/shared/build/**",
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
assets/*
|
||||
src/test/examples/**
|
||||
src/test/integration/**
|
||||
src/test/unit-sources/**
|
||||
src/**/fixtures/**
|
||||
src/test/mochitest/**
|
||||
bin/
|
||||
packages/**/fixtures/**
|
||||
node_modules
|
||||
out
|
|
@ -2,6 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* global __dirname */
|
||||
|
||||
/**
|
||||
* NOTE: This file does not apply to builds in MC. This config is used for
|
||||
* our Jest tests and for webpack bundle builds.
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* global __dirname */
|
||||
|
||||
const sharedJestConfig = require(`${__dirname}/../shared/test-helpers/shared-jest.config`);
|
||||
|
||||
const { resolve } = require("path");
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* global __dirname */
|
||||
|
||||
const { resolve } = require("path");
|
||||
const rootDir = resolve(__dirname);
|
||||
module.exports = {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { MultiLocalizationHelper } = require("devtools/shared/l10n");
|
||||
const {
|
||||
FluentL10n,
|
||||
|
@ -158,7 +160,7 @@ class DebuggerPanel {
|
|||
|
||||
unHighlightDomElement() {
|
||||
if (!this._unhighlight) {
|
||||
return;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this._unhighlight();
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
test/examples/**
|
||||
test/integration/**
|
||||
test/unit-sources/**
|
||||
**/fixtures/**
|
||||
test/mochitest/**
|
|
@ -3,8 +3,11 @@
|
|||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
import React, { PureComponent } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { connect } from "../../../utils/connect";
|
||||
import actions from "../../../actions";
|
||||
|
||||
import {
|
||||
getTruncatedFileName,
|
||||
getDisplayPath,
|
||||
|
@ -15,6 +18,7 @@ import {
|
|||
getHasSiblingOfSameName,
|
||||
getBreakpointsForSource,
|
||||
getContext,
|
||||
getThreadForSource,
|
||||
} from "../../../selectors";
|
||||
|
||||
import SourceIcon from "../../shared/SourceIcon";
|
||||
|
@ -22,6 +26,15 @@ import SourceIcon from "../../shared/SourceIcon";
|
|||
import showContextMenu from "./BreakpointHeadingsContextMenu";
|
||||
|
||||
class BreakpointHeading extends PureComponent {
|
||||
static get propTypes() {
|
||||
return {
|
||||
cx: PropTypes.object,
|
||||
sources: PropTypes.array,
|
||||
hasSiblingOfSameName: PropTypes.bool,
|
||||
selectSource: PropTypes.func.isRequired,
|
||||
thread: PropTypes.object,
|
||||
};
|
||||
}
|
||||
onContextMenu = e => {
|
||||
showContextMenu({ ...this.props, contextMenuEvent: e });
|
||||
};
|
||||
|
@ -33,6 +46,7 @@ class BreakpointHeading extends PureComponent {
|
|||
source,
|
||||
hasSiblingOfSameName,
|
||||
selectSource,
|
||||
thread,
|
||||
} = this.props;
|
||||
|
||||
const path = getDisplayPath(source, sources);
|
||||
|
@ -41,7 +55,7 @@ class BreakpointHeading extends PureComponent {
|
|||
return (
|
||||
<div
|
||||
className="breakpoint-heading"
|
||||
title={getFileURL(source, false)}
|
||||
title={`${thread?.name} - ${getFileURL(source, false)}`}
|
||||
onClick={() => selectSource(cx, source.id)}
|
||||
onContextMenu={this.onContextMenu}
|
||||
>
|
||||
|
@ -64,6 +78,7 @@ const mapStateToProps = (state, { source }) => ({
|
|||
cx: getContext(state),
|
||||
hasSiblingOfSameName: getHasSiblingOfSameName(state, source),
|
||||
breakpointsForSource: getBreakpointsForSource(state, source.id),
|
||||
thread: getThreadForSource(state, source.id),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
import { isOriginalId, originalToGeneratedId } from "devtools-source-map";
|
||||
import { createSelector } from "reselect";
|
||||
import { getSourceActorsForSource } from "../selectors/sources";
|
||||
|
||||
export const getThreads = createSelector(
|
||||
state => state.threads.threads,
|
||||
|
@ -39,6 +41,26 @@ export function getThread(state, threadActor) {
|
|||
return getAllThreads(state).find(thread => thread.actor === threadActor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the thread for a specified source
|
||||
*
|
||||
* @param {Object} state
|
||||
* @param {String} sourceId
|
||||
* @return {Object} The thread object for the source.
|
||||
*/
|
||||
export function getThreadForSource(state, sourceId) {
|
||||
const actors = getSourceActorsForSource(
|
||||
state,
|
||||
isOriginalId(sourceId) ? originalToGeneratedId(sourceId) : sourceId
|
||||
);
|
||||
|
||||
if (!actors || !actors.length) {
|
||||
console.error(`Error no source actors exist for source ${sourceId}`);
|
||||
return null;
|
||||
}
|
||||
return getThread(state, actors[0].thread);
|
||||
}
|
||||
|
||||
// checks if a path begins with a thread actor
|
||||
// e.g "server1.conn0.child1/workerTarget22/context1/dbg-workers.glitch.me"
|
||||
export function startsWithThreadActor(state, path) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"use strict";
|
||||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// General rule from /.eslintrc.js only accept folders matching **/test*/browser*/
|
||||
// where is this folder doesn't match, so manually apply browser test config
|
||||
|
|
|
@ -51,6 +51,7 @@ skip-if = debug # Window leaks: bug 1575332
|
|||
[browser_dbg-breakpoints-debugger-statement.js]
|
||||
[browser_dbg-breakpoints-duplicate-functions.js]
|
||||
[browser_dbg-breakpoints-in-evaled-sources.js]
|
||||
[browser_dbg-breakpoints-list.js]
|
||||
[browser_dbg-breakpoints-popup.js]
|
||||
[browser_dbg-browser-content-toolbox.js]
|
||||
skip-if = !e10s || verify # This test is only valid in e10s
|
||||
|
|
|
@ -14,5 +14,5 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
await resume(dbg);
|
||||
await invokeInTab("checkACState");
|
||||
ok(true, "No AudioContext state transition are caused by the debugger")
|
||||
ok(true, "No AudioContext state transition are caused by the debugger");
|
||||
});
|
||||
|
|
|
@ -23,7 +23,9 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
async function testSourcesOnNavigation() {
|
||||
info("Test that sources appear in the debugger when navigating using the BFCache")
|
||||
info(
|
||||
"Test that sources appear in the debugger when navigating using the BFCache"
|
||||
);
|
||||
const dbg = await initDebugger("doc-bfcache1.html");
|
||||
|
||||
await navigate(dbg, "doc-bfcache2.html", "doc-bfcache2.html");
|
||||
|
@ -51,7 +53,7 @@ async function testDebuggerPauseStateOnNavigation() {
|
|||
await navigate(dbg, "doc-bfcache2.html");
|
||||
await waitForSources(dbg, "doc-bfcache2.html");
|
||||
|
||||
await goBack(EXAMPLE_URL + "doc-bfcache1.html");
|
||||
await goBack(`${EXAMPLE_URL}doc-bfcache1.html`);
|
||||
await waitForSources(dbg, "doc-bfcache1.html");
|
||||
|
||||
await reload(dbg);
|
||||
|
@ -59,7 +61,7 @@ async function testDebuggerPauseStateOnNavigation() {
|
|||
|
||||
ok(dbg.toolbox.isHighlighted("jsdebugger"), "Debugger is highlighted");
|
||||
|
||||
await goForward(EXAMPLE_URL + "doc-bfcache2.html");
|
||||
await goForward(`${EXAMPLE_URL}doc-bfcache2.html`);
|
||||
|
||||
await waitUntil(() => !dbg.toolbox.isHighlighted("jsdebugger"));
|
||||
ok(true, "Debugger is not highlighted");
|
||||
|
|
|
@ -26,7 +26,11 @@ add_task(async function() {
|
|||
const dbg = await initDebugger("doc-blackbox-all.html");
|
||||
|
||||
info("Loads the source file and sets a breakpoint at line 2.");
|
||||
await waitForSources(dbg, SOURCE_FILES.nestedSource, SOURCE_FILES.codeReload1);
|
||||
await waitForSources(
|
||||
dbg,
|
||||
SOURCE_FILES.nestedSource,
|
||||
SOURCE_FILES.codeReload1
|
||||
);
|
||||
await selectSource(dbg, SOURCE_FILES.nestedSource);
|
||||
await addBreakpoint(dbg, SOURCE_FILES.nestedSource, 2);
|
||||
|
||||
|
@ -42,14 +46,30 @@ add_task(async function() {
|
|||
rightClickEl(dbg, sourceTreeFolderNodeEls[1]);
|
||||
await waitForContextMenu(dbg);
|
||||
await openContextMenuSubmenu(dbg, NODE_SELECTORS.nodeBlackBoxAll);
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeBlackBoxAllInside, "Ignore files in this directory");
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeBlackBoxAllOutside, "Ignore files outside this directory");
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeBlackBoxAllInside,
|
||||
"Ignore files in this directory"
|
||||
);
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeBlackBoxAllOutside,
|
||||
"Ignore files outside this directory"
|
||||
);
|
||||
selectContextMenuItem(dbg, NODE_SELECTORS.nodeBlackBoxAllInside);
|
||||
await waitForBlackboxCount(dbg, 1);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
|
||||
is(findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed, true, "nested-source.js is blackboxed");
|
||||
is(findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed, false, "code_reload_1.js is not blackboxed");
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed,
|
||||
true,
|
||||
"nested-source.js is blackboxed"
|
||||
);
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed,
|
||||
false,
|
||||
"code_reload_1.js is not blackboxed"
|
||||
);
|
||||
|
||||
info("The invoked function is blackboxed and the debugger does not pause.");
|
||||
invokeInTab("computeSomething");
|
||||
|
@ -59,14 +79,30 @@ add_task(async function() {
|
|||
rightClickEl(dbg, sourceTreeFolderNodeEls[2]);
|
||||
await waitForContextMenu(dbg);
|
||||
await openContextMenuSubmenu(dbg, NODE_SELECTORS.nodeBlackBoxAll);
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeBlackBoxAllInside, "Ignore files in this directory");
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeUnBlackBoxAllOutside, "Unignore files outside this directory");
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeBlackBoxAllInside,
|
||||
"Ignore files in this directory"
|
||||
);
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeUnBlackBoxAllOutside,
|
||||
"Unignore files outside this directory"
|
||||
);
|
||||
selectContextMenuItem(dbg, NODE_SELECTORS.nodeUnBlackBoxAllOutside);
|
||||
await waitForBlackboxCount(dbg, 0);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
|
||||
is(findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed, false, "nested-source.js is not blackboxed");
|
||||
is(findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed, false, "code_reload_1.js is not blackboxed");
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed,
|
||||
false,
|
||||
"nested-source.js is not blackboxed"
|
||||
);
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed,
|
||||
false,
|
||||
"code_reload_1.js is not blackboxed"
|
||||
);
|
||||
|
||||
info("All sources are unblackboxed and the debugger pauses on line 2.");
|
||||
invokeInTab("computeSomething");
|
||||
|
@ -76,24 +112,48 @@ add_task(async function() {
|
|||
info("Blackbox files in this group.");
|
||||
rightClickEl(dbg, sourceTreeRootNodeEl);
|
||||
await waitForContextMenu(dbg);
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeBlackBoxAllInside, "Ignore files in this group");
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeBlackBoxAllInside,
|
||||
"Ignore files in this group"
|
||||
);
|
||||
selectContextMenuItem(dbg, NODE_SELECTORS.nodeBlackBoxAllInside);
|
||||
await waitForBlackboxCount(dbg, 2);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
|
||||
is(findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed, true, "nested-source.js is blackboxed");
|
||||
is(findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed, true, "code_reload_1.js is blackboxed");
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed,
|
||||
true,
|
||||
"nested-source.js is blackboxed"
|
||||
);
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed,
|
||||
true,
|
||||
"code_reload_1.js is blackboxed"
|
||||
);
|
||||
|
||||
info("Unblackbox files in this group.");
|
||||
rightClickEl(dbg, sourceTreeRootNodeEl);
|
||||
await waitForContextMenu(dbg);
|
||||
await assertContextMenuLabel(dbg, NODE_SELECTORS.nodeUnBlackBoxAllInside, "Unignore files in this group");
|
||||
await assertContextMenuLabel(
|
||||
dbg,
|
||||
NODE_SELECTORS.nodeUnBlackBoxAllInside,
|
||||
"Unignore files in this group"
|
||||
);
|
||||
selectContextMenuItem(dbg, NODE_SELECTORS.nodeUnBlackBoxAllInside);
|
||||
await waitForBlackboxCount(dbg, 0);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
|
||||
is(findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed, false, "nested-source.js is not blackboxed");
|
||||
is(findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed, false, "code_reload_1.js is not blackboxed");
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.nestedSource).isBlackBoxed,
|
||||
false,
|
||||
"nested-source.js is not blackboxed"
|
||||
);
|
||||
is(
|
||||
findSource(dbg, SOURCE_FILES.codeReload1).isBlackBoxed,
|
||||
false,
|
||||
"code_reload_1.js is not blackboxed"
|
||||
);
|
||||
});
|
||||
|
||||
function waitForBlackboxCount(dbg, count) {
|
||||
|
|
|
@ -8,11 +8,6 @@ add_task(async function() {
|
|||
const dbg = await initDebugger("doc-sourcemaps3.html");
|
||||
dbg.actions.toggleMapScopes();
|
||||
|
||||
const {
|
||||
selectors: { getBreakpoint, getBreakpointCount },
|
||||
getState,
|
||||
} = dbg;
|
||||
|
||||
await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
|
||||
|
||||
const sortedSrc = findSource(dbg, "sorted.js");
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/* 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↩
|
||||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// This test covers all the blackboxing functionality relating to a selected
|
||||
// source open in the debugger editor.
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(5);
|
||||
|
||||
|
@ -12,11 +11,16 @@ const contextMenuItems = {
|
|||
ignoreSource: { selector: "#node-menu-blackbox", label: "Ignore source" },
|
||||
unignoreSource: { selector: "#node-menu-blackbox", label: "Unignore source" },
|
||||
ignoreLines: { selector: "#node-menu-blackbox-lines", label: "Ignore lines" },
|
||||
unignoreLines: { selector: "#node-menu-blackbox-lines", label: "Unignore lines" },
|
||||
unignoreLines: {
|
||||
selector: "#node-menu-blackbox-lines",
|
||||
label: "Unignore lines",
|
||||
},
|
||||
ignoreLine: { selector: "#node-menu-blackbox-line", label: "Ignore line" },
|
||||
unignoreLine: { selector: "#node-menu-blackbox-line", label: "Unignore line" },
|
||||
}
|
||||
|
||||
unignoreLine: {
|
||||
selector: "#node-menu-blackbox-line",
|
||||
label: "Unignore line",
|
||||
},
|
||||
};
|
||||
|
||||
// Tests basic functionality for blackbox source and blackbox single and multiple lines
|
||||
add_task(async function testAllBlackBox() {
|
||||
|
@ -81,7 +85,10 @@ add_task(async function testBlackBoxOnReload() {
|
|||
info("Ignoring line 7 to 9");
|
||||
selectEditorLines(dbg, 7, 9);
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.unignoreSource, contextMenuItems.ignoreLines]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.unignoreSource,
|
||||
contextMenuItems.ignoreLines,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox-lines");
|
||||
|
||||
await reload(dbg, file);
|
||||
|
@ -98,17 +105,24 @@ async function testBlackBoxSource(dbg, source) {
|
|||
|
||||
info("blackbox the whole simple4.js source file");
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.ignoreSource, contextMenuItems.ignoreLine]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.ignoreSource,
|
||||
contextMenuItems.ignoreLine,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox");
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
||||
info("The debugger statement on line 2 and the breakpoint on line 8 should not be hit")
|
||||
info(
|
||||
"The debugger statement on line 2 and the breakpoint on line 8 should not be hit"
|
||||
);
|
||||
assertNotPaused(dbg);
|
||||
|
||||
info("unblackbox the whole source");
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.unignoreSource]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.unignoreSource,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox");
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
@ -130,7 +144,10 @@ async function testBlackBoxMultipleLines(dbg, source) {
|
|||
info("Blackbox lines 7 to 13");
|
||||
selectEditorLines(dbg, 7, 13);
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.ignoreSource, contextMenuItems.ignoreLines]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.ignoreSource,
|
||||
contextMenuItems.ignoreLines,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox-lines");
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
@ -140,13 +157,18 @@ async function testBlackBoxMultipleLines(dbg, source) {
|
|||
assertPausedAtSourceAndLine(dbg, source.id, 2);
|
||||
await resumeAndWaitForPauseCounter(dbg);
|
||||
|
||||
info("The breakpoint set on line 8 should not get hit as its within the blackboxed range");
|
||||
info(
|
||||
"The breakpoint set on line 8 should not get hit as its within the blackboxed range"
|
||||
);
|
||||
assertNotPaused(dbg);
|
||||
|
||||
info ("Unblackbox lines 7 to 13");
|
||||
info("Unblackbox lines 7 to 13");
|
||||
selectEditorLines(dbg, 7, 13);
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.unignoreSource, contextMenuItems.unignoreLines]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.unignoreSource,
|
||||
contextMenuItems.unignoreLines,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox-lines");
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
@ -170,7 +192,6 @@ async function testBlackBoxSingleLine(dbg, source) {
|
|||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.ignoreLine]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox-line");
|
||||
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
||||
// assert the pause at the breakpoint set on line 8
|
||||
|
@ -183,7 +204,10 @@ async function testBlackBoxSingleLine(dbg, source) {
|
|||
info("Un-blackbox line 2 of funcA()");
|
||||
selectEditorLines(dbg, 2, 2);
|
||||
await openContextMenu(dbg, "CodeMirrorLines");
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [contextMenuItems.unignoreSource, contextMenuItems.unignoreLine]);
|
||||
await assertBlackBoxBoxContextMenuItems(dbg, [
|
||||
contextMenuItems.unignoreSource,
|
||||
contextMenuItems.unignoreLine,
|
||||
]);
|
||||
await selectBlackBoxContextMenuItem(dbg, "blackbox-line");
|
||||
|
||||
invokeInTab("funcA");
|
||||
|
@ -206,8 +230,8 @@ async function testBlackBoxSingleLine(dbg, source) {
|
|||
async function resumeAndWaitForPauseCounter(dbg) {
|
||||
const prevThreadPauseCounter = getThreadContext(dbg).pauseCounter;
|
||||
await resume(dbg);
|
||||
return waitFor(() =>
|
||||
getThreadContext(dbg).pauseCounter > prevThreadPauseCounter
|
||||
return waitFor(
|
||||
() => getThreadContext(dbg).pauseCounter > prevThreadPauseCounter
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -219,7 +243,10 @@ async function resumeAndWaitForPauseCounter(dbg) {
|
|||
* e.g When the whole source is blackboxed, we should only see the "Unignore source"
|
||||
* context menu item.
|
||||
*/
|
||||
async function assertBlackBoxBoxContextMenuItems(dbg, expectedContextMenuItems) {
|
||||
async function assertBlackBoxBoxContextMenuItems(
|
||||
dbg,
|
||||
expectedContextMenuItems
|
||||
) {
|
||||
for (const item of expectedContextMenuItems) {
|
||||
await assertContextMenuLabel(dbg, item.selector, item.label);
|
||||
}
|
||||
|
@ -261,6 +288,8 @@ async function selectBlackBoxContextMenuItem(dbg, itemName) {
|
|||
* @params {Number} endLine
|
||||
*/
|
||||
function selectEditorLines(dbg, startLine, endLine) {
|
||||
getCM(dbg).setSelection({ line: startLine - 1, ch: 0 }, { line: endLine - 1, ch: 0 });
|
||||
getCM(dbg).setSelection(
|
||||
{ line: startLine - 1, ch: 0 },
|
||||
{ line: endLine - 1, ch: 0 }
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,12 @@ const TEST_URL = testServer.urlFor("index.html");
|
|||
|
||||
// Assert the behavior of the gutter that grays out non-breakable lines
|
||||
add_task(async function testBreakableLinesOverReloads() {
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URL, "index.html", "script.js", "original.js");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URL,
|
||||
"index.html",
|
||||
"script.js",
|
||||
"original.js"
|
||||
);
|
||||
|
||||
info("Assert breakable lines of the first html page load");
|
||||
await assertBreakableLines(dbg, "index.html", 20, [[17], [18]]);
|
||||
|
@ -17,17 +22,22 @@ add_task(async function testBreakableLinesOverReloads() {
|
|||
// because the sourcemap replaces the content of the original file
|
||||
// and appends a few lines with a "WEBPACK FOOTER" comment
|
||||
// All the appended lines are empty lines or comments, so none of them are breakable.
|
||||
await assertBreakableLines(dbg, "original.js", 13, [[1,3], [5,8]]);
|
||||
await assertBreakableLines(dbg, "original.js", 13, [
|
||||
[1, 3],
|
||||
[5, 8],
|
||||
]);
|
||||
|
||||
info("Assert breakable lines of the simple first load of script.js");
|
||||
await assertBreakableLines(dbg, "script.js", 3, [[1], [3]]);
|
||||
|
||||
info("Reload the page, wait for sources and assert that breakable lines get updated");
|
||||
info(
|
||||
"Reload the page, wait for sources and assert that breakable lines get updated"
|
||||
);
|
||||
testServer.switchToNextVersion();
|
||||
await reload(dbg, "index.html", "script.js", "original.js");
|
||||
|
||||
info("Assert breakable lines of the more complex second load of script.js");
|
||||
await assertBreakableLines(dbg, "script.js", 23, [[2], [13,23]]);
|
||||
await assertBreakableLines(dbg, "script.js", 23, [[2], [13, 23]]);
|
||||
|
||||
info("Assert breakable lines of the second html page load");
|
||||
await assertBreakableLines(dbg, "index.html", 22, [[16], [18]]);
|
||||
|
@ -35,11 +45,11 @@ add_task(async function testBreakableLinesOverReloads() {
|
|||
info("Assert breakable lines of the second orignal file");
|
||||
// See first assertion about original.js,
|
||||
// the size of original.js doesn't match the size of the test file
|
||||
await assertBreakableLines(dbg, "original.js", 18, [[1,3], [8,11], [13]]);
|
||||
await assertBreakableLines(dbg, "original.js", 18, [[1, 3], [8, 11], [13]]);
|
||||
});
|
||||
|
||||
function shouldLineBeBreakable(breakableLines, line) {
|
||||
for(const range of breakableLines) {
|
||||
for (const range of breakableLines) {
|
||||
if (range.length == 2) {
|
||||
if (line >= range[0] && line <= range[1]) {
|
||||
return true;
|
||||
|
@ -49,7 +59,10 @@ function shouldLineBeBreakable(breakableLines, line) {
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
ok(false, "Ranges of breakable lines should only be made of arrays, with one item for single lines, or two items for subsequent breakable lines");
|
||||
ok(
|
||||
false,
|
||||
"Ranges of breakable lines should only be made of arrays, with one item for single lines, or two items for subsequent breakable lines"
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -57,9 +70,20 @@ function shouldLineBeBreakable(breakableLines, line) {
|
|||
|
||||
async function assertBreakableLines(dbg, file, numberOfLines, breakableLines) {
|
||||
await selectSource(dbg, file);
|
||||
const editorLines = dbg.win.document.querySelectorAll(".CodeMirror-lines .CodeMirror-code > div");
|
||||
is(editorLines.length, numberOfLines, `We show the expected number of lines in CodeMirror for ${file}`);
|
||||
for(let line = 1; line <= numberOfLines; line++) {
|
||||
assertLineIsBreakable(dbg, file, line, shouldLineBeBreakable(breakableLines, line));
|
||||
const editorLines = dbg.win.document.querySelectorAll(
|
||||
".CodeMirror-lines .CodeMirror-code > div"
|
||||
);
|
||||
is(
|
||||
editorLines.length,
|
||||
numberOfLines,
|
||||
`We show the expected number of lines in CodeMirror for ${file}`
|
||||
);
|
||||
for (let line = 1; line <= numberOfLines; line++) {
|
||||
assertLineIsBreakable(
|
||||
dbg,
|
||||
file,
|
||||
line,
|
||||
shouldLineBeBreakable(breakableLines, line)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
// debugger.
|
||||
|
||||
add_task(async function() {
|
||||
const url = EXAMPLE_URL + "doc-script-switching.html";
|
||||
const url = `${EXAMPLE_URL}doc-script-switching.html`;
|
||||
const toolbox = await openNewTabAndToolbox(url, "webconsole");
|
||||
|
||||
// Type "debugger" into console
|
||||
let wrapper = toolbox.getPanel("webconsole").hud.ui.wrapper;
|
||||
const wrapper = toolbox.getPanel("webconsole").hud.ui.wrapper;
|
||||
const onSelected = toolbox.once("jsdebugger-selected");
|
||||
wrapper.dispatchEvaluateExpression("debugger");
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ add_task(async function() {
|
|||
const dbg = await initDebugger("doc-scripts.html");
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState,
|
||||
} = dbg;
|
||||
|
||||
await selectSource(dbg, "doc-scripts.html");
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
add_task(async function() {
|
||||
const toolbox = await initPane("doc-scripts.html", "webconsole", [
|
||||
["devtools.debugger.skip-pausing", true]
|
||||
["devtools.debugger.skip-pausing", true],
|
||||
]);
|
||||
await navigateTo(EXAMPLE_URL + "doc-debugger-statements.html");
|
||||
await navigateTo(`${EXAMPLE_URL}doc-debugger-statements.html`);
|
||||
|
||||
await hasConsoleMessage({ toolbox }, 'done!')
|
||||
ok(true, 'We reached the end');
|
||||
await hasConsoleMessage({ toolbox }, "done!");
|
||||
ok(true, "We reached the end");
|
||||
});
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "long.js");
|
||||
|
||||
let cursorPosition = { line: undefined, column: undefined };
|
||||
|
||||
await selectSource(dbg, "long.js");
|
||||
await waitForSelectedSource(dbg, "long.js");
|
||||
|
||||
info("toggle conditional panel with shortcut: no breakpoints, default cursorPosition");
|
||||
info(
|
||||
"toggle conditional panel with shortcut: no breakpoints, default cursorPosition"
|
||||
);
|
||||
pressKey(dbg, "toggleCondPanel");
|
||||
await waitForConditionalPanelFocus(dbg);
|
||||
ok(
|
||||
|
@ -28,7 +28,9 @@ add_task(async function() {
|
|||
info("close conditional panel");
|
||||
pressKey(dbg, "Escape");
|
||||
|
||||
info("toggle conditional panel with shortcut: cursor on line 32, no breakpoints");
|
||||
info(
|
||||
"toggle conditional panel with shortcut: cursor on line 32, no breakpoints"
|
||||
);
|
||||
// codemirror editor offset: cursorPosition will be line + 1, column + 1
|
||||
getCM(dbg).setCursor({ line: 31, ch: 1 });
|
||||
pressKey(dbg, "toggleCondPanel");
|
||||
|
@ -46,43 +48,59 @@ add_task(async function() {
|
|||
info("close conditional panel");
|
||||
pressKey(dbg, "Escape");
|
||||
|
||||
info("add active column breakpoint on line 32 and set cursorPosition")
|
||||
info("add active column breakpoint on line 32 and set cursorPosition");
|
||||
await enableFirstBreakpoint(dbg);
|
||||
getCM(dbg).setCursor({ line: 31, ch: 1 });
|
||||
info("toggle conditional panel with shortcut and add condition to first breakpoint");
|
||||
info(
|
||||
"toggle conditional panel with shortcut and add condition to first breakpoint"
|
||||
);
|
||||
setConditionalBreakpoint(dbg, "1");
|
||||
await waitForCondition(dbg, 1);
|
||||
const firstBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 2);
|
||||
is(firstBreakpoint.options.condition, "1", "first breakpoint created with condition using shortcut");
|
||||
is(
|
||||
firstBreakpoint.options.condition,
|
||||
"1",
|
||||
"first breakpoint created with condition using shortcut"
|
||||
);
|
||||
|
||||
info("set cursor at second breakpoint position and activate breakpoint");
|
||||
getCM(dbg).setCursor({ line: 31, ch: 25 });
|
||||
|
||||
await enableSecondBreakpoint(dbg);
|
||||
info("toggle conditional panel with shortcut and add condition to second breakpoint");
|
||||
info(
|
||||
"toggle conditional panel with shortcut and add condition to second breakpoint"
|
||||
);
|
||||
setConditionalBreakpoint(dbg, "2");
|
||||
await waitForCondition(dbg, 2);
|
||||
const secondBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 26);
|
||||
is(secondBreakpoint.options.condition, "2", "second breakpoint created with condition using shortcut");
|
||||
is(
|
||||
secondBreakpoint.options.condition,
|
||||
"2",
|
||||
"second breakpoint created with condition using shortcut"
|
||||
);
|
||||
|
||||
info("set cursor position near first breakpoint, toggle conditional panel and edit breakpoint");
|
||||
info(
|
||||
"set cursor position near first breakpoint, toggle conditional panel and edit breakpoint"
|
||||
);
|
||||
getCM(dbg).setCursor({ line: 31, ch: 7 });
|
||||
info("toggle conditional panel and edit condition using shortcut");
|
||||
setConditionalBreakpoint(dbg, "2");
|
||||
ok(
|
||||
!! waitForCondition(dbg, "12"),
|
||||
!!waitForCondition(dbg, "12"),
|
||||
"breakpoint closest to cursor position has been edited"
|
||||
);
|
||||
|
||||
info("close conditional panel");
|
||||
pressKey(dbg, "Escape");
|
||||
|
||||
info("set cursor position near second breakpoint, toggle conditional panel and edit breakpoint");
|
||||
info(
|
||||
"set cursor position near second breakpoint, toggle conditional panel and edit breakpoint"
|
||||
);
|
||||
getCM(dbg).setCursor({ line: 31, ch: 21 });
|
||||
info("toggle conditional panel and edit condition using shortcut");
|
||||
setConditionalBreakpoint(dbg, "3");
|
||||
ok(
|
||||
!! waitForCondition(dbg, "13"),
|
||||
!!waitForCondition(dbg, "13"),
|
||||
"breakpoint closest to cursor position has been edited"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -12,8 +12,6 @@ const EVALED_SOURCE_TEXT = `setTimeout(function() {
|
|||
console.log("SECOND LINE");
|
||||
}, 10)`;
|
||||
|
||||
// doc-scripts.html contains some javascript on which we can set breakpoints.
|
||||
const REGULAR_SOURCE_FILE = "doc-scripts.html";
|
||||
/**
|
||||
* Check against blank debugger panel issues when attempting to restore
|
||||
* breakpoints set in evaled sources (Bug 1720512).
|
||||
|
@ -43,12 +41,16 @@ add_task(async function() {
|
|||
info("Wait for the debugger to be paused on the debugger statement");
|
||||
await waitForPaused(dbg);
|
||||
|
||||
is(getCM(dbg).getValue(), EVALED_SOURCE_TEXT, "The debugger is showing the evaled source");
|
||||
is(
|
||||
getCM(dbg).getValue(),
|
||||
EVALED_SOURCE_TEXT,
|
||||
"The debugger is showing the evaled source"
|
||||
);
|
||||
|
||||
const evaledSource = dbg.selectors.getSelectedSource();
|
||||
assertPausedAtSourceAndLine(dbg, evaledSource.id, 2);
|
||||
|
||||
info("Add a breakpoint in the evaled source")
|
||||
info("Add a breakpoint in the evaled source");
|
||||
await addBreakpoint(dbg, evaledSource, 3);
|
||||
|
||||
info("Resume and check that we hit the breakpoint");
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Testing displaying breakpoints in the breakpoints list and the tooltip
|
||||
// shows the thread information.
|
||||
|
||||
add_task(async function testBreakpointsListForMultipleTargets() {
|
||||
const dbg = await initDebugger(
|
||||
"doc_dbg-fission-frame-sources.html",
|
||||
"simple1.js",
|
||||
"simple2.js"
|
||||
);
|
||||
|
||||
info("Add breakpoint to the source (simple1.js) in the main thread");
|
||||
await selectSource(dbg, "simple1.js");
|
||||
const source1 = findSource(dbg, "simple1.js");
|
||||
await addBreakpoint(dbg, "simple1.js", 5);
|
||||
|
||||
info("Add breakpoint to the source (simple2.js) in the frame");
|
||||
await selectSource(dbg, "simple2.js");
|
||||
const source2 = findSource(dbg, "simple2.js");
|
||||
await addBreakpoint(dbg, "simple2.js", 3);
|
||||
|
||||
const breakpointHeadings = findAllElements(dbg, "breakpointHeadings");
|
||||
const breakpointItems = findAllElements(dbg, "breakpointItems");
|
||||
|
||||
is(
|
||||
breakpointHeadings.length,
|
||||
2,
|
||||
"The breakpoint list shows two breakpoints sources"
|
||||
);
|
||||
is(
|
||||
breakpointItems.length,
|
||||
2,
|
||||
"The breakpoint list shows only two breakpoints"
|
||||
);
|
||||
|
||||
is(
|
||||
breakpointHeadings[0].title,
|
||||
`Main Thread - ${source1.url}`,
|
||||
"The breakpoint heading tooltip shows the thread and source info for the first breakpoint"
|
||||
);
|
||||
is(
|
||||
breakpointHeadings[0].textContent,
|
||||
"simple1.js",
|
||||
"The info displayed for the breakpoint heading of the 1st breakpoint is correct"
|
||||
);
|
||||
is(
|
||||
breakpointItems[0].textContent,
|
||||
"func();5:17",
|
||||
"The info displayed for the 1st breakpoint is correct"
|
||||
);
|
||||
|
||||
// With fission and EFT disabled all the sources are going to be under the Main Thread
|
||||
const expectedThreadName =
|
||||
!Services.prefs.getBoolPref("fission.autostart") &&
|
||||
!Services.prefs.getBoolPref("devtools.every-frame-target.enabled")
|
||||
? "Main Thread"
|
||||
: "Test remote frame sources";
|
||||
|
||||
is(
|
||||
breakpointHeadings[1].title,
|
||||
`${expectedThreadName} - ${source2.url}`,
|
||||
"The breakpoint heading tooltip shows the thread and source info for the second breakpoint"
|
||||
);
|
||||
is(
|
||||
breakpointHeadings[1].textContent,
|
||||
"simple2.js",
|
||||
"The info displayed for the breakpoint heading of the 2nd breakpoint is correct"
|
||||
);
|
||||
is(
|
||||
breakpointItems[1].textContent,
|
||||
"return x + y;3:4",
|
||||
"The info displayed for the 2nd breakpoint is correct"
|
||||
);
|
||||
|
||||
await removeBreakpoint(dbg, source1.id, 5);
|
||||
await removeBreakpoint(dbg, source2.id, 3);
|
||||
});
|
||||
|
||||
add_task(async function testBreakpointsListForOriginalFiles() {
|
||||
const dbg = await initDebugger("doc-sourcemaps.html", "entry.js");
|
||||
|
||||
info("Add breakpoint to the entry.js (original source) in the main thread");
|
||||
await selectSource(dbg, "entry.js");
|
||||
const source = findSource(dbg, "entry.js");
|
||||
await addBreakpoint(dbg, "entry.js", 5);
|
||||
|
||||
const breakpointHeadings = findAllElements(dbg, "breakpointHeadings");
|
||||
const breakpointItems = findAllElements(dbg, "breakpointItems");
|
||||
|
||||
is(
|
||||
breakpointHeadings.length,
|
||||
1,
|
||||
"The breakpoint list shows one breakpoints sources"
|
||||
);
|
||||
is(
|
||||
breakpointItems.length,
|
||||
1,
|
||||
"The breakpoint list shows only one breakpoints"
|
||||
);
|
||||
|
||||
is(
|
||||
breakpointHeadings[0].title,
|
||||
`Main Thread - ${source.url}`,
|
||||
"The breakpoint heading tooltip shows the thread and source info for the first breakpoint"
|
||||
);
|
||||
is(
|
||||
breakpointHeadings[0].textContent,
|
||||
"entry.js",
|
||||
"The info displayed for the breakpoint heading of the 1st breakpoint is correct"
|
||||
);
|
||||
is(
|
||||
breakpointItems[0].textContent,
|
||||
"output(times2(1));5",
|
||||
"The info displayed for the 1st breakpoint is correct"
|
||||
);
|
||||
|
||||
await removeBreakpoint(dbg, source.id, 5);
|
||||
});
|
|
@ -5,20 +5,20 @@
|
|||
// Verify that we hit breakpoints on popups
|
||||
|
||||
const TEST_URI = "https://example.org/document-builder.sjs?html=main page";
|
||||
const POPUP_URL = "https://example.com/document-builder.sjs?html=" + escape(`popup for breakpoints
|
||||
const POPUP_URL = `https://example.com/document-builder.sjs?html=${escape(`popup for breakpoints
|
||||
<script>
|
||||
var paused = true;
|
||||
console.log('popup');
|
||||
paused = false;
|
||||
</script>
|
||||
`);
|
||||
const POPUP_DEBUGGER_STATEMENT_URL = "https://example.com/document-builder.sjs?html="+ escape(`popup with debugger;
|
||||
`)}`;
|
||||
const POPUP_DEBUGGER_STATEMENT_URL = `https://example.com/document-builder.sjs?html=${escape(`popup with debugger;
|
||||
<script>
|
||||
var paused = true;
|
||||
debugger;
|
||||
paused = false;
|
||||
</script>
|
||||
`);
|
||||
`)}`;
|
||||
|
||||
function isPopupPaused(popupBrowsingContext) {
|
||||
return SpecialPowers.spawn(popupBrowsingContext, [], function(url) {
|
||||
|
@ -31,12 +31,20 @@ async function openPopup(popupUrl, browser = gBrowser.selectedBrowser) {
|
|||
gBrowser.tabContainer,
|
||||
"TabSelect"
|
||||
);
|
||||
const popupBrowsingContext = await SpecialPowers.spawn(browser, [popupUrl], function(url) {
|
||||
const popup = content.open(url);
|
||||
return popup.browsingContext;
|
||||
});
|
||||
const popupBrowsingContext = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[popupUrl],
|
||||
function(url) {
|
||||
const popup = content.open(url);
|
||||
return popup.browsingContext;
|
||||
}
|
||||
);
|
||||
await onPopupTabSelected;
|
||||
is(gBrowser.selectedBrowser.browsingContext, popupBrowsingContext, "The popup is the selected tab");
|
||||
is(
|
||||
gBrowser.selectedBrowser.browsingContext,
|
||||
popupBrowsingContext,
|
||||
"The popup is the selected tab"
|
||||
);
|
||||
return popupBrowsingContext;
|
||||
}
|
||||
|
||||
|
@ -55,9 +63,7 @@ add_task(async function testPausedByBreakpoint() {
|
|||
await pushPref("devtools.popups.debug", true);
|
||||
|
||||
info("Test breakpoints set in popup scripts");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URI
|
||||
);
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
|
||||
|
||||
info("Open the popup in order to be able to set a breakpoint");
|
||||
const firstPopupBrowsingContext = await openPopup(POPUP_URL);
|
||||
|
@ -72,7 +78,11 @@ add_task(async function testPausedByBreakpoint() {
|
|||
info("Re-open the popup");
|
||||
const popupBrowsingContext = await openPopup(POPUP_URL);
|
||||
await waitForPaused(dbg);
|
||||
is(await isPopupPaused(popupBrowsingContext), true, "The popup is really paused");
|
||||
is(
|
||||
await isPopupPaused(popupBrowsingContext),
|
||||
true,
|
||||
"The popup is really paused"
|
||||
);
|
||||
|
||||
// As we still spawn distinct reducer sources when the sources come from distinct
|
||||
// thread/target (i.e. behavior of `makeSourceId`).
|
||||
|
@ -84,42 +94,58 @@ add_task(async function testPausedByBreakpoint() {
|
|||
.filter(s => s.url.includes(POPUP_URL));
|
||||
return list.length == 2 ? list : null;
|
||||
});
|
||||
is(sources[0], source, "The first source is the previous one, related to the closed popup");
|
||||
is(
|
||||
sources[0],
|
||||
source,
|
||||
"The first source is the previous one, related to the closed popup"
|
||||
);
|
||||
const newSource = sources[1];
|
||||
isnot(source, newSource, "The second one is related to the new popup and is different");
|
||||
isnot(
|
||||
source,
|
||||
newSource,
|
||||
"The second one is related to the new popup and is different"
|
||||
);
|
||||
isnot(source.id, newSource.id, "The source IDs are different");
|
||||
assertPausedAtSourceAndLine(dbg, newSource.id, 4);
|
||||
|
||||
await resume(dbg);
|
||||
is(await isPopupPaused(popupBrowsingContext), false, "The popup resumed its execution");
|
||||
is(
|
||||
await isPopupPaused(popupBrowsingContext),
|
||||
false,
|
||||
"The popup resumed its execution"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function testPausedByDebuggerStatement() {
|
||||
info("Test debugger statements in popup scripts");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URI
|
||||
);
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
|
||||
|
||||
info("Open a popup with a debugger statement");
|
||||
const popupBrowsingContext = await openPopup(POPUP_DEBUGGER_STATEMENT_URL);
|
||||
await waitForPaused(dbg);
|
||||
is(await isPopupPaused(popupBrowsingContext), true, "The popup is really paused");
|
||||
is(
|
||||
await isPopupPaused(popupBrowsingContext),
|
||||
true,
|
||||
"The popup is really paused"
|
||||
);
|
||||
|
||||
const source = findSource(dbg, POPUP_DEBUGGER_STATEMENT_URL);
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 4);
|
||||
|
||||
await resume(dbg);
|
||||
is(await isPopupPaused(popupBrowsingContext), false, "The popup resumed its execution");
|
||||
is(
|
||||
await isPopupPaused(popupBrowsingContext),
|
||||
false,
|
||||
"The popup resumed its execution"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function testPausedInTwoPopups() {
|
||||
info("Test being paused in two popup at the same time");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URI
|
||||
);
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
|
||||
|
||||
info("Open the popup in order to be able to set a breakpoint");
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
const browser = gBrowser.selectedBrowser;
|
||||
const popupBrowsingContext = await openPopup(POPUP_URL);
|
||||
const source = await waitForSource(dbg, POPUP_URL);
|
||||
|
||||
|
@ -133,17 +159,34 @@ add_task(async function testPausedInTwoPopups() {
|
|||
const firstPopupBrowsingContext = await openPopup(POPUP_URL);
|
||||
await waitForPaused(dbg);
|
||||
const { targetCommand } = dbg.commands;
|
||||
const firstTarget = targetCommand.getAllTargets([targetCommand.TYPES.FRAME]).find(targetFront => targetFront.url == POPUP_URL);
|
||||
is(firstTarget.browsingContextID, firstPopupBrowsingContext.id, "The popup target matches the popup BrowsingContext");
|
||||
const firstTarget = targetCommand
|
||||
.getAllTargets([targetCommand.TYPES.FRAME])
|
||||
.find(targetFront => targetFront.url == POPUP_URL);
|
||||
is(
|
||||
firstTarget.browsingContextID,
|
||||
firstPopupBrowsingContext.id,
|
||||
"The popup target matches the popup BrowsingContext"
|
||||
);
|
||||
const firstThread = (await firstTarget.getFront("thread")).actorID;
|
||||
is(dbg.selectors.getCurrentThread(), firstThread, "The popup thread is automatically selected on pause");
|
||||
is(await isPopupPaused(firstPopupBrowsingContext), true, "The first popup is really paused");
|
||||
is(
|
||||
dbg.selectors.getCurrentThread(),
|
||||
firstThread,
|
||||
"The popup thread is automatically selected on pause"
|
||||
);
|
||||
is(
|
||||
await isPopupPaused(firstPopupBrowsingContext),
|
||||
true,
|
||||
"The first popup is really paused"
|
||||
);
|
||||
|
||||
info("Open a second popup which will also hit the breakpoint");
|
||||
let onAvailable;
|
||||
const onNewTarget = new Promise(resolve => {
|
||||
onAvailable = ({ targetFront }) => {
|
||||
if (targetFront.url == POPUP_URL && targetFront.browsingContextID != firstPopupBrowsingContext.id) {
|
||||
if (
|
||||
targetFront.url == POPUP_URL &&
|
||||
targetFront.browsingContextID != firstPopupBrowsingContext.id
|
||||
) {
|
||||
targetCommand.unwatchTargets({
|
||||
types: [targetCommand.TYPES.FRAME],
|
||||
onAvailable,
|
||||
|
@ -159,33 +202,57 @@ add_task(async function testPausedInTwoPopups() {
|
|||
const secondPopupBrowsingContext = await openPopup(POPUP_URL, browser);
|
||||
info("Wait for second popup's target");
|
||||
const popupTarget = await onNewTarget;
|
||||
is(popupTarget.browsingContextID, secondPopupBrowsingContext.id, "The new target matches the popup WindowGlobal");
|
||||
is(
|
||||
popupTarget.browsingContextID,
|
||||
secondPopupBrowsingContext.id,
|
||||
"The new target matches the popup WindowGlobal"
|
||||
);
|
||||
const secondThread = (await popupTarget.getFront("thread")).actorID;
|
||||
await waitForPausedThread(dbg, secondThread);
|
||||
is(dbg.selectors.getCurrentThread(), secondThread, "The second popup thread is automatically selected on pause");
|
||||
is(await isPopupPaused(secondPopupBrowsingContext), true, "The second popup is really paused");
|
||||
is(
|
||||
dbg.selectors.getCurrentThread(),
|
||||
secondThread,
|
||||
"The second popup thread is automatically selected on pause"
|
||||
);
|
||||
is(
|
||||
await isPopupPaused(secondPopupBrowsingContext),
|
||||
true,
|
||||
"The second popup is really paused"
|
||||
);
|
||||
|
||||
info("Resume the execution of the second popup");
|
||||
await resume(dbg);
|
||||
is(await isPopupPaused(secondPopupBrowsingContext), false, "The second popup resumed its execution");
|
||||
is(await isPopupPaused(firstPopupBrowsingContext), true, "The first popup is still paused");
|
||||
is(
|
||||
await isPopupPaused(secondPopupBrowsingContext),
|
||||
false,
|
||||
"The second popup resumed its execution"
|
||||
);
|
||||
is(
|
||||
await isPopupPaused(firstPopupBrowsingContext),
|
||||
true,
|
||||
"The first popup is still paused"
|
||||
);
|
||||
|
||||
info("Resume the execution of the first popup");
|
||||
await dbg.actions.selectThread(getContext(dbg), firstThread);
|
||||
await resume(dbg);
|
||||
is(await isPopupPaused(firstPopupBrowsingContext), false, "The first popup resumed its execution");
|
||||
is(
|
||||
await isPopupPaused(firstPopupBrowsingContext),
|
||||
false,
|
||||
"The first popup resumed its execution"
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function testClosingOriginalTab() {
|
||||
info("Test closing the toolbox on the original tab while the popup is kept open");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URI
|
||||
info(
|
||||
"Test closing the toolbox on the original tab while the popup is kept open"
|
||||
);
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
|
||||
await dbg.toolbox.selectTool("webconsole");
|
||||
|
||||
info("Open a popup");
|
||||
const originalTab = gBrowser.selectedTab;
|
||||
const popupBrowsingContext = await openPopup("about:blank");
|
||||
await openPopup("about:blank");
|
||||
await wait(1000);
|
||||
const popupTab = gBrowser.selectedTab;
|
||||
gBrowser.selectedTab = originalTab;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
|
||||
// This tests breakpoints resyncing when source content changes
|
||||
// after reload.
|
||||
// IMPORTANT NOTE: This test currently test scenarios with breakpoint shifting
|
||||
|
@ -17,34 +16,37 @@ const httpServer = createTestHTTPServer();
|
|||
httpServer.registerContentType("html", "text/html");
|
||||
httpServer.registerContentType("js", "application/javascript");
|
||||
|
||||
httpServer.registerPathHandler("/doc-breakpoint-reload.html", (request, response) => {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.write(`<!DOCTYPE html>
|
||||
httpServer.registerPathHandler(
|
||||
"/doc-breakpoint-reload.html",
|
||||
(request, response) => {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.write(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="/script.js"></script>
|
||||
</head>
|
||||
</html>
|
||||
`);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
let views = 0;
|
||||
httpServer.registerPathHandler("/script.js", (request, response) => {
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
// The script contents to serve on reload of script.js. Each relaod
|
||||
// cycles through the script content.
|
||||
const content = [
|
||||
// CONTENT 1: Source content with 1 function
|
||||
// The breakpoint will be set on line 3 (i.e with the `return` statement)
|
||||
`function bar() {
|
||||
const content = [
|
||||
// CONTENT 1: Source content with 1 function
|
||||
// The breakpoint will be set on line 3 (i.e with the `return` statement)
|
||||
`function bar() {
|
||||
const prefix = "long";
|
||||
return prefix + "bar";
|
||||
}
|
||||
console.log(bar());`,
|
||||
|
||||
// CONTENT 2: Source content with 2 functions, where the breakpoint is now in a
|
||||
// different function though the line does not change.
|
||||
`function foo() {
|
||||
// CONTENT 2: Source content with 2 functions, where the breakpoint is now in a
|
||||
// different function though the line does not change.
|
||||
`function foo() {
|
||||
const prefix = "long";
|
||||
return prefix + "foo";
|
||||
}
|
||||
|
@ -55,9 +57,9 @@ function bar() {
|
|||
}
|
||||
console.log(bar(), foo());`,
|
||||
|
||||
// CONTENT 3: Source content with comments and 1 function, where the breakpoint is
|
||||
// is now at a line with comments (non-breakable line).
|
||||
`// This is a random comment which is here
|
||||
// CONTENT 3: Source content with comments and 1 function, where the breakpoint is
|
||||
// is now at a line with comments (non-breakable line).
|
||||
`// This is a random comment which is here
|
||||
// to move the function a couple of lines
|
||||
// down, making sure the breakpoint is on
|
||||
// a non-breakable line.
|
||||
|
@ -67,10 +69,10 @@ function bar() {
|
|||
}
|
||||
console.log(bar());`,
|
||||
|
||||
// CONTENT 4: Source content with just a comment where the line which the breakpoint
|
||||
// is supposed to be on no longer exists.
|
||||
`// one line comment`,
|
||||
];
|
||||
// CONTENT 4: Source content with just a comment where the line which the breakpoint
|
||||
// is supposed to be on no longer exists.
|
||||
`// one line comment`,
|
||||
];
|
||||
|
||||
response.write(content[views % content.length]);
|
||||
views++;
|
||||
|
@ -80,24 +82,30 @@ const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`;
|
|||
|
||||
add_task(async function testBreakpointInFunctionRelocation() {
|
||||
info("Start test for relocation of breakpoint set in a function");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(BASE_URL + "doc-breakpoint-reload.html", "script.js");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
`${BASE_URL}doc-breakpoint-reload.html`,
|
||||
"script.js"
|
||||
);
|
||||
|
||||
let source = findSource(dbg, "script.js");
|
||||
await selectSource(dbg, source);
|
||||
|
||||
info("Add breakpoint in bar()")
|
||||
info("Add breakpoint in bar()");
|
||||
await addBreakpoint(dbg, source, 3);
|
||||
|
||||
info("Assert the text content on line 3 to make sure the breakpoint was set in bar()");
|
||||
info(
|
||||
"Assert the text content on line 3 to make sure the breakpoint was set in bar()"
|
||||
);
|
||||
assertTextContentOnLine(dbg, 3, 'return prefix + "bar";');
|
||||
|
||||
info("Reload should change the source content to CONTENT 2 i.e 2 functions foo() and bar()");
|
||||
info(
|
||||
"Reload should change the source content to CONTENT 2 i.e 2 functions foo() and bar()"
|
||||
);
|
||||
await reload(dbg);
|
||||
await waitForPaused(dbg);
|
||||
|
||||
source = findSource(dbg, "script.js");
|
||||
|
||||
|
||||
info("Assert that the breakpoint pauses on line 3");
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 3);
|
||||
|
||||
|
@ -119,7 +127,9 @@ add_task(async function testBreakpointInFunctionRelocation() {
|
|||
|
||||
await resume(dbg);
|
||||
|
||||
info("Reload should change the source content to CONTENT 3 i.e comments and 1 function bar()")
|
||||
info(
|
||||
"Reload should change the source content to CONTENT 3 i.e comments and 1 function bar()"
|
||||
);
|
||||
await reload(dbg);
|
||||
await waitForSelectedSource(dbg, "script.js");
|
||||
|
||||
|
@ -133,17 +143,23 @@ add_task(async function testBreakpointInFunctionRelocation() {
|
|||
} else {
|
||||
await assertNotPaused(dbg);
|
||||
|
||||
info("Assert that the breakpoint is still visible on line 3 which is a non-breakable line");
|
||||
info(
|
||||
"Assert that the breakpoint is still visible on line 3 which is a non-breakable line"
|
||||
);
|
||||
await assertBreakpoint(dbg, 3);
|
||||
}
|
||||
|
||||
info("Assert the text content on line 3 to make sure the breakpoint is set line 3 of the comment");
|
||||
assertTextContentOnLine(dbg, 3, '// down, making sure the breakpoint is on');
|
||||
info(
|
||||
"Assert the text content on line 3 to make sure the breakpoint is set line 3 of the comment"
|
||||
);
|
||||
assertTextContentOnLine(dbg, 3, "// down, making sure the breakpoint is on");
|
||||
|
||||
info("Check that only one breakpoint still exists");
|
||||
is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists");
|
||||
|
||||
info("Reload should change the source content to CONTENT 4 which is just a one comment line")
|
||||
info(
|
||||
"Reload should change the source content to CONTENT 4 which is just a one comment line"
|
||||
);
|
||||
await reload(dbg);
|
||||
await waitForSelectedSource(dbg, "script.js");
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ add_task(async function() {
|
|||
await reload(dbg);
|
||||
await waitForPaused(dbg);
|
||||
|
||||
info("Assert that the source is not long.js")
|
||||
info("Assert that the source is not long.js");
|
||||
// Adding this is redundant but just to make it explicit that we
|
||||
// make sure long.js should not exist yet
|
||||
assertSourceDoesNotExist(dbg, "long.js");
|
||||
|
|
|
@ -38,15 +38,24 @@ add_task(async function testReloadingStableOriginalSource() {
|
|||
info("Check that breakpoint is on the first line within the function `foo`");
|
||||
assertTextContentOnLine(dbg, 6, expectedOriginalFileContentOnBreakpointLine);
|
||||
|
||||
info("Check that the breakpoint is displayed in correct location in bundle.js (generated source)")
|
||||
info(
|
||||
"Check that the breakpoint is displayed in correct location in bundle.js (generated source)"
|
||||
);
|
||||
await selectSource(dbg, "bundle.js");
|
||||
await assertBreakpoint(dbg, 82);
|
||||
assertTextContentOnLine(dbg, 82, expectedGeneratedFileContentOnBreakpointLine);
|
||||
assertTextContentOnLine(
|
||||
dbg,
|
||||
82,
|
||||
expectedGeneratedFileContentOnBreakpointLine
|
||||
);
|
||||
|
||||
await closeTab(dbg, "bundle.js");
|
||||
|
||||
info("Reload with a new version of the file");
|
||||
const waitUntilNewBreakpointIsSet = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
const waitUntilNewBreakpointIsSet = waitForDispatch(
|
||||
dbg.store,
|
||||
"SET_BREAKPOINT"
|
||||
);
|
||||
testServer.switchToNextVersion();
|
||||
await reload(dbg, "bundle.js", "original.js");
|
||||
await waitUntilNewBreakpointIsSet;
|
||||
|
@ -68,10 +77,14 @@ add_task(async function testReloadingStableOriginalSource() {
|
|||
await assertPausedAtSourceAndLine(dbg, originalSource.id, 9);
|
||||
await assertBreakpoint(dbg, 9);
|
||||
|
||||
info("Check that though the breakpoint has moved, it is still on the first line within the function `foo`")
|
||||
info(
|
||||
"Check that though the breakpoint has moved, it is still on the first line within the function `foo`"
|
||||
);
|
||||
assertTextContentOnLine(dbg, 9, expectedOriginalFileContentOnBreakpointLine);
|
||||
|
||||
info("Check that the breakpoint is displayed in correct location in bundle.js (generated source)")
|
||||
info(
|
||||
"Check that the breakpoint is displayed in correct location in bundle.js (generated source)"
|
||||
);
|
||||
await selectSource(dbg, "bundle.js");
|
||||
// This scrolls the line into view so the content
|
||||
// on the line is rendered and avaliable for dom querying.
|
||||
|
@ -80,7 +93,11 @@ add_task(async function testReloadingStableOriginalSource() {
|
|||
const generatedSource = findSource(dbg, "bundle.js");
|
||||
await assertPausedAtSourceAndLine(dbg, generatedSource.id, 82);
|
||||
await assertBreakpoint(dbg, 82);
|
||||
assertTextContentOnLine(dbg, 82, expectedGeneratedFileContentOnBreakpointLine);
|
||||
assertTextContentOnLine(
|
||||
dbg,
|
||||
82,
|
||||
expectedGeneratedFileContentOnBreakpointLine
|
||||
);
|
||||
|
||||
await closeTab(dbg, "bundle.js");
|
||||
|
||||
|
@ -120,7 +137,10 @@ add_task(async function testReloadingStableOriginalSource() {
|
|||
add_task(async function testReloadingReplacedOriginalSource() {
|
||||
testServer.backToFirstVersion();
|
||||
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_URL, "removed-original.js");
|
||||
const dbg = await initDebuggerWithAbsoluteURL(
|
||||
TEST_URL,
|
||||
"removed-original.js"
|
||||
);
|
||||
|
||||
info("Add initial breakpoint");
|
||||
await selectSource(dbg, "removed-original.js");
|
||||
|
@ -141,7 +161,9 @@ add_task(async function testReloadingReplacedOriginalSource() {
|
|||
|
||||
await resume(dbg);
|
||||
|
||||
info("Reload, which should remove the original file and a add a new original file which will replace its content in the generated file");
|
||||
info(
|
||||
"Reload, which should remove the original file and a add a new original file which will replace its content in the generated file"
|
||||
);
|
||||
const syncBp = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
testServer.switchToNextVersion();
|
||||
await reload(dbg);
|
||||
|
@ -162,7 +184,9 @@ add_task(async function testReloadingReplacedOriginalSource() {
|
|||
is(breakpoint.location.line, 2);
|
||||
is(breakpoint.generatedLocation.line, 78);
|
||||
|
||||
info("Reload a last time to remove both original and generated sources entirely");
|
||||
info(
|
||||
"Reload a last time to remove both original and generated sources entirely"
|
||||
);
|
||||
testServer.switchToNextVersion();
|
||||
await reload(dbg);
|
||||
|
||||
|
@ -170,9 +194,15 @@ add_task(async function testReloadingReplacedOriginalSource() {
|
|||
await wait(1000);
|
||||
|
||||
info("Assert that sources and breakpoints are gone and we aren't paused");
|
||||
ok(!sourceExists(dbg, "removed-original.js"), "removed-original is not present");
|
||||
ok(
|
||||
!sourceExists(dbg, "removed-original.js"),
|
||||
"removed-original is not present"
|
||||
);
|
||||
ok(!sourceExists(dbg, "new-original.js"), "new-original is not present");
|
||||
ok(!sourceExists(dbg, "replaced-bundle.js"), "replaced-bundle is not present");
|
||||
assertNotPaused(dbg);
|
||||
ok(
|
||||
!sourceExists(dbg, "replaced-bundle.js"),
|
||||
"replaced-bundle is not present"
|
||||
);
|
||||
assertNotPaused(dbg);
|
||||
is(dbg.selectors.getBreakpointCount(), 0, "We no longer have any breakpoint");
|
||||
});
|
||||
|
|
|
@ -37,7 +37,10 @@ add_task(async function() {
|
|||
|
||||
rightClickElement(dbg, "breakpointItem", 2);
|
||||
await waitForContextMenu(dbg);
|
||||
const disableBreakpointDispatch = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
const disableBreakpointDispatch = waitForDispatch(
|
||||
dbg.store,
|
||||
"SET_BREAKPOINT"
|
||||
);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableSelf);
|
||||
await disableBreakpointDispatch;
|
||||
|
||||
|
|
|
@ -2,29 +2,27 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Tests that the debugger is succesfully loaded in the Browser Content Toolbox.
|
||||
*/
|
||||
|
||||
const {
|
||||
gDevToolsBrowser
|
||||
gDevToolsBrowser,
|
||||
} = require("devtools/client/framework/devtools-browser");
|
||||
|
||||
add_task(async function() {
|
||||
clearDebuggerPreferences();
|
||||
|
||||
info("Open a tab pointing to doc-scripts.html");
|
||||
await addTab(EXAMPLE_URL + "doc-scripts.html");
|
||||
await addTab(`${EXAMPLE_URL}doc-scripts.html`);
|
||||
|
||||
info("Open the Browser Content Toolbox");
|
||||
let toolbox = await gDevToolsBrowser.openContentProcessToolbox(gBrowser);
|
||||
const toolbox = await gDevToolsBrowser.openContentProcessToolbox(gBrowser);
|
||||
|
||||
info("Select the debugger");
|
||||
await toolbox.selectTool("jsdebugger");
|
||||
|
||||
let dbg = createDebuggerContext(toolbox);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
ok(dbg, "Debugger context is available");
|
||||
|
||||
info("Create a breakpoint");
|
||||
|
@ -42,7 +40,7 @@ add_task(async function() {
|
|||
is(bp.disabled, false, "breakpoint is enabled");
|
||||
|
||||
info("Close the browser toolbox window");
|
||||
let onToolboxDestroyed = toolbox.once("destroyed");
|
||||
const onToolboxDestroyed = toolbox.once("destroyed");
|
||||
toolbox.win.top.close();
|
||||
await onToolboxDestroyed;
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
/* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Test that the debugger pauses in the multiprocess browser toolbox even when
|
||||
// it hasn't been opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(4);
|
||||
|
||||
/* import-globals-from ../../../framework/browser-toolbox/test/helpers-browser-toolbox.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js",
|
||||
this
|
||||
|
@ -36,7 +35,7 @@ add_task(async function() {
|
|||
});
|
||||
// ToolboxTask.spawn pass input arguments by stringify them via string concatenation.
|
||||
// This mean we have to stringify the input object, but don't have to parse it from the task.
|
||||
await ToolboxTask.spawn(JSON.stringify(selectors), async (_selectors) => {
|
||||
await ToolboxTask.spawn(JSON.stringify(selectors), async _selectors => {
|
||||
this.selectors = _selectors;
|
||||
});
|
||||
|
||||
|
@ -44,6 +43,7 @@ add_task(async function() {
|
|||
|
||||
// The debugger should automatically be selected.
|
||||
await ToolboxTask.spawn(null, async () => {
|
||||
/* global gToolbox */
|
||||
await waitUntil(() => gToolbox.currentToolId == "jsdebugger");
|
||||
});
|
||||
ok(true, "Debugger selected");
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
/* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Test that all kinds of workers show up properly in the multiprocess browser
|
||||
// toolbox.
|
||||
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(4);
|
||||
|
||||
/* import-globals-from ../../../framework/browser-toolbox/test/helpers-browser-toolbox.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js",
|
||||
this
|
||||
|
@ -20,25 +19,29 @@ add_task(async function() {
|
|||
await pushPref("dom.serviceWorkers.testing.enabled", true);
|
||||
|
||||
const ToolboxTask = await initBrowserToolboxTask();
|
||||
await ToolboxTask.importFunctions({ waitUntil, waitForAllTargetsToBeAttached });
|
||||
await ToolboxTask.importFunctions({
|
||||
waitUntil,
|
||||
waitForAllTargetsToBeAttached,
|
||||
});
|
||||
|
||||
await addTab(EXAMPLE_URL + "doc-all-workers.html");
|
||||
await addTab(`${EXAMPLE_URL}doc-all-workers.html`);
|
||||
|
||||
await ToolboxTask.spawn(null, async () => {
|
||||
/* global gToolbox */
|
||||
await gToolbox.selectTool("jsdebugger");
|
||||
const dbg = gToolbox.getCurrentPanel().panelWin.dbg;
|
||||
|
||||
await waitUntil(() => {
|
||||
const threads = dbg.selectors.getThreads();
|
||||
function hasWorker(workerName) {
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
return threads.some(({ name }) => name == workerName);
|
||||
}
|
||||
return (
|
||||
hasWorker("simple-worker.js") &&
|
||||
hasWorker("shared-worker.js") &&
|
||||
hasWorker("service-worker.sjs")
|
||||
);
|
||||
|
||||
function hasWorker(workerName) {
|
||||
return threads.some(({ name }) => name == workerName);
|
||||
}
|
||||
});
|
||||
|
||||
await waitForAllTargetsToBeAttached(gToolbox.commands.targetCommand);
|
||||
|
|
|
@ -75,7 +75,6 @@ function isFrameSelected(dbg, index, title) {
|
|||
|
||||
const {
|
||||
selectors: { getSelectedFrame, getCurrentThread },
|
||||
getState,
|
||||
} = dbg;
|
||||
|
||||
const frame = getSelectedFrame(getCurrentThread());
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
|
||||
/**
|
||||
* Tests that a chrome debugger can be created in a new process.
|
||||
*/
|
||||
|
@ -14,7 +13,9 @@ PromiseTestUtils.allowMatchingRejectionsGlobally(/NS_ERROR_FAILURE/);
|
|||
|
||||
requestLongerTimeout(5);
|
||||
|
||||
const { BrowserToolboxLauncher } = ChromeUtils.import("resource://devtools/client/framework/browser-toolbox/Launcher.jsm");
|
||||
const { BrowserToolboxLauncher } = ChromeUtils.import(
|
||||
"resource://devtools/client/framework/browser-toolbox/Launcher.jsm"
|
||||
);
|
||||
let gProcess = undefined;
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -38,10 +39,10 @@ add_task(async function() {
|
|||
"The remote debugger process doesn't have a pid (?!)"
|
||||
);
|
||||
|
||||
info("process location: " + gProcess._dbgProcess.location);
|
||||
info("process pid: " + gProcess._dbgProcess.pid);
|
||||
info("process name: " + gProcess._dbgProcess.processName);
|
||||
info("process sig: " + gProcess._dbgProcess.processSignature);
|
||||
info(`process location: ${gProcess._dbgProcess.location}`);
|
||||
info(`process pid: ${gProcess._dbgProcess.pid}`);
|
||||
info(`process name: ${gProcess._dbgProcess.processName}`);
|
||||
info(`process sig: ${gProcess._dbgProcess.processSignature}`);
|
||||
|
||||
ok(
|
||||
gProcess._dbgProfilePath,
|
||||
|
@ -54,7 +55,7 @@ add_task(async function() {
|
|||
"The remote debugger profile isn't where we expect it!"
|
||||
);
|
||||
|
||||
info("profile path: " + gProcess._dbgProfilePath);
|
||||
info(`profile path: ${gProcess._dbgProfilePath}`);
|
||||
|
||||
await gProcess.close();
|
||||
});
|
||||
|
@ -76,9 +77,9 @@ function onClose() {
|
|||
"The remote debugger process didn't die cleanly."
|
||||
);
|
||||
|
||||
info("process exit value: " + gProcess._dbgProcess.exitCode);
|
||||
info(`process exit value: ${gProcess._dbgProcess.exitCode}`);
|
||||
|
||||
info("profile path: " + gProcess._dbgProfilePath);
|
||||
info(`profile path: ${gProcess._dbgProfilePath}`);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
// will jump the debugger to that call.
|
||||
add_task(async function() {
|
||||
await pushPref("devtools.debugger.features.command-click", true);
|
||||
info("Checking to see if command click will jump the debugger to another highlighted call.");
|
||||
info(
|
||||
"Checking to see if command click will jump the debugger to another highlighted call."
|
||||
);
|
||||
const dbg = await initDebugger("doc-command-click.html", "simple4.js");
|
||||
|
||||
const source = findSource(dbg, "simple4.js");
|
||||
|
@ -14,7 +16,6 @@ add_task(async function() {
|
|||
await selectSource(dbg, source);
|
||||
await waitForSelectedSource(dbg, source);
|
||||
|
||||
|
||||
invokeInTab("funcA");
|
||||
await waitForPaused(dbg);
|
||||
await waitForInlinePreviews(dbg);
|
||||
|
@ -29,6 +30,8 @@ add_task(async function() {
|
|||
await waitForDispatch(dbg.store, "RESUME");
|
||||
await waitForPaused(dbg);
|
||||
assertDebugLine(dbg, 3, 2);
|
||||
const nocalls = dbg.win.document.querySelectorAll(".highlight-function-calls");
|
||||
const nocalls = dbg.win.document.querySelectorAll(
|
||||
".highlight-function-calls"
|
||||
);
|
||||
is(nocalls.length, 0);
|
||||
});
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Return a promise with a reference to jsterm, opening the split
|
||||
// console if necessary. This cleans up the split console pref so
|
||||
// it won't pollute other tests.
|
||||
|
@ -9,7 +13,10 @@ add_task(async function() {
|
|||
true
|
||||
);
|
||||
|
||||
const dbg = await initDebugger("doc-script-switching.html", "script-switching-01.js");
|
||||
const dbg = await initDebugger(
|
||||
"doc-script-switching.html",
|
||||
"script-switching-01.js"
|
||||
);
|
||||
|
||||
await selectSource(dbg, "script-switching-01.js");
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests opening the console first, clicking a link
|
||||
// opens the editor at the correct location.
|
||||
|
||||
|
@ -19,12 +17,10 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
async function waitForLink(toolbox, messageText) {
|
||||
const { hud } = toolbox.getPanel("webconsole");
|
||||
|
||||
return waitFor(async () => {
|
||||
const [message] = await findConsoleMessages(toolbox, messageText);
|
||||
if (!message) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return message.querySelector(".frame-link-source");
|
||||
});
|
||||
|
|
|
@ -22,11 +22,7 @@ add_task(async function() {
|
|||
// console if necessary. This cleans up the split console pref so
|
||||
// it won't pollute other tests.
|
||||
function getSplitConsole(dbg) {
|
||||
const { toolbox, win } = dbg;
|
||||
|
||||
if (!win) {
|
||||
win = toolbox.win;
|
||||
}
|
||||
const { toolbox } = dbg;
|
||||
|
||||
if (!toolbox.splitConsole) {
|
||||
pressKey(dbg, "Escape");
|
||||
|
@ -35,7 +31,7 @@ function getSplitConsole(dbg) {
|
|||
return new Promise(resolve => {
|
||||
toolbox.getPanelWhenReady("webconsole").then(() => {
|
||||
ok(toolbox.splitConsole, "Split console is shown.");
|
||||
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
|
||||
const jsterm = toolbox.getPanel("webconsole").hud.jsterm;
|
||||
resolve(jsterm);
|
||||
});
|
||||
});
|
||||
|
@ -46,4 +42,4 @@ async function evaluate(dbg, expression) {
|
|||
const { hud } = toolbox.getPanel("webconsole");
|
||||
const msg = await evaluateExpressionInConsole(hud, expression);
|
||||
return msg.innerText;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
add_task(async function() {
|
||||
Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
|
||||
const dbg = await initDebugger("doc-script-switching.html", "script-switching-01.js");
|
||||
const dbg = await initDebugger(
|
||||
"doc-script-switching.html",
|
||||
"script-switching-01.js"
|
||||
);
|
||||
|
||||
await selectSource(dbg, "script-switching-01.js");
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that the content scripts are listed in the source tree.
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -13,7 +11,6 @@ add_task(async function() {
|
|||
let dbg = await initDebugger("doc-content-script-sources.html");
|
||||
await clickElement(dbg, "sourceDirectoryLabel", 2);
|
||||
|
||||
|
||||
await selectContentScriptSources(dbg);
|
||||
await closeTab(dbg, "content_script.js");
|
||||
|
||||
|
@ -71,22 +68,22 @@ async function installAndStartExtension() {
|
|||
window.onload = () => {};
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
js: ["content_script.js"],
|
||||
matches: ["https://example.com/*"],
|
||||
run_at: "document_start"
|
||||
}
|
||||
]
|
||||
run_at: "document_start",
|
||||
},
|
||||
],
|
||||
},
|
||||
files: {
|
||||
"content_script.js": contentScript
|
||||
}
|
||||
"content_script.js": contentScript,
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,12 @@ Services.scriptloader.loadSubScript(
|
|||
* breakpoint, that's why we need the page itself to have a way of updating
|
||||
* the attribute.
|
||||
*/
|
||||
const TEST_COM_URI =
|
||||
`https://example.com/document-builder.sjs?html=` +
|
||||
encodeURI(
|
||||
`<input disabled=""/>
|
||||
const TEST_COM_URI = `https://example.com/document-builder.sjs?html=${encodeURI(
|
||||
`<input disabled=""/>
|
||||
<button onclick="document.querySelector('input').toggleAttribute('disabled')">
|
||||
click me
|
||||
</button>`
|
||||
);
|
||||
)}`;
|
||||
|
||||
// Embed the example.com test page in an example.org iframe.
|
||||
const TEST_URI = `https://example.org/document-builder.sjs?html=
|
||||
|
@ -75,20 +73,16 @@ add_task(async function() {
|
|||
checkbox.click();
|
||||
await waitFor(() => !checkbox.checked);
|
||||
|
||||
info(
|
||||
"Click the button in the remote iframe, should not hit the breakpoint"
|
||||
);
|
||||
info("Click the button in the remote iframe, should not hit the breakpoint");
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("button", {}, frameBC);
|
||||
|
||||
info("Wait until the input is enabled");
|
||||
await asyncWaitUntil(() =>
|
||||
SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
||||
return SpecialPowers.spawn(
|
||||
content.document.querySelector("iframe"),
|
||||
[],
|
||||
() => !content.document.querySelector("input").disabled
|
||||
);
|
||||
})
|
||||
SpecialPowers.spawn(
|
||||
frameBC,
|
||||
[],
|
||||
() => !content.document.querySelector("input").disabled
|
||||
)
|
||||
);
|
||||
is(isPaused(dbg), false, "DOM breakpoint should not have been hit");
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* 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
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Test that eager evaluation skips breakpoints and debugger statements
|
||||
|
||||
|
@ -10,8 +8,6 @@ add_task(async function() {
|
|||
const dbg = await initDebugger("doc-strict.html");
|
||||
const { hud } = await getDebuggerSplitConsole(dbg);
|
||||
|
||||
const toolbox = await gDevTools.getToolboxForTab(gBrowser.selectedTab);
|
||||
|
||||
await addBreakpoint(dbg, "doc-strict.html", 15);
|
||||
setInputValue(hud, "strict()");
|
||||
await waitForEagerEvaluationResult(hud, `3`);
|
||||
|
|
|
@ -11,7 +11,6 @@ PromiseTestUtils.allowMatchingRejectionsGlobally(/NS_ERROR_NOT_INITIALIZED/);
|
|||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple1.js");
|
||||
const { getState } = dbg;
|
||||
const source = findSource(dbg, "simple1.js");
|
||||
|
||||
await selectSource(dbg, source);
|
||||
|
@ -33,10 +32,6 @@ add_task(async function() {
|
|||
info("Ensure clicking on gutter to add breakpoint will un-blackbox source");
|
||||
const dbg = await initDebugger("doc-sourcemaps3.html");
|
||||
dbg.actions.toggleMapScopes();
|
||||
const {
|
||||
selectors: { getBreakpoint, getBreakpointCount },
|
||||
getState
|
||||
} = dbg;
|
||||
await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
|
||||
|
||||
info("blackbox the source");
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "long.js");
|
||||
const {
|
||||
selectors: { getSource, getSourceContent }
|
||||
selectors: { getSourceContent },
|
||||
} = dbg;
|
||||
|
||||
// The source itself doesn't even exist yet, and using
|
||||
|
|
|
@ -11,16 +11,10 @@ add_task(async function() {
|
|||
// which is the slowest part of this and make it run faster, but to
|
||||
// fix a frequent failure allow a longer timeout.
|
||||
const dbg = await initDebugger("doc-scripts.html");
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState,
|
||||
} = dbg;
|
||||
const simple1 = findSource(dbg, "simple1.js");
|
||||
const simple2 = findSource(dbg, "simple2.js");
|
||||
|
||||
info("Set the initial breakpoint.");
|
||||
await selectSource(dbg, "simple1.js");
|
||||
await addBreakpoint(dbg, simple1, 4);
|
||||
await addBreakpoint(dbg, "simple1.js", 4);
|
||||
|
||||
info("Call the function that we set a breakpoint in.");
|
||||
invokeInTab("main");
|
||||
|
|
|
@ -16,7 +16,7 @@ add_task(async function() {
|
|||
"Module",
|
||||
["config", "{\u2026}"],
|
||||
"EmberRouter:Class()",
|
||||
"Router:Class()"
|
||||
"Router:Class()",
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Tests early event breakpoints and event breakpoints in a remote frame.
|
||||
// Tests early event breakpoints and event breakpoints in a remote frame.
|
||||
|
||||
add_task(async function () {
|
||||
await pushPref(
|
||||
add_task(async function() {
|
||||
await pushPref(
|
||||
"devtools.debugger.features.event-listeners-breakpoints",
|
||||
true
|
||||
);
|
||||
|
@ -21,7 +21,7 @@ add_task(async function () {
|
|||
await dbg.actions.addEventListenerBreakpoints([
|
||||
"event.mouse.click",
|
||||
"event.xhr.load",
|
||||
"timer.timeout.set"
|
||||
"timer.timeout.set",
|
||||
]);
|
||||
|
||||
info("Assert early timeout event breakpoint gets hit");
|
||||
|
@ -36,7 +36,7 @@ add_task(async function () {
|
|||
info("Assert event breakpoints work in remote frame");
|
||||
await invokeAndAssertBreakpoints(dbg);
|
||||
|
||||
info("reload the iframe")
|
||||
info("reload the iframe");
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () =>
|
||||
content.wrappedJSObject.reloadIframe()
|
||||
);
|
||||
|
@ -69,7 +69,10 @@ function assertPauseLocation(dbg, line, url = "event-breakpoints.js") {
|
|||
|
||||
async function invokeInTabRemoteFrame(fnc, ...args) {
|
||||
info(`Invoking in tab remote frame: ${fnc}(${args.map(uneval).join(",")})`);
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [fnc, args], function (_fnc, _args) {
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [fnc, args], function(
|
||||
_fnc,
|
||||
_args
|
||||
) {
|
||||
return SpecialPowers.spawn(
|
||||
content.document.querySelector("iframe"),
|
||||
[_fnc, _args],
|
||||
|
@ -77,4 +80,3 @@ async function invokeInTabRemoteFrame(fnc, ...args) {
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
* Test the watch expressions update when selecting a different thread in the thread panel.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_COM_URI =
|
||||
URL_ROOT_COM + "examples/doc_dbg-fission-frame-sources.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM}examples/doc_dbg-fission-frame-sources.html`;
|
||||
|
||||
add_task(async function() {
|
||||
// Load a test page with a remote frame and wait for both sources to be visible.
|
||||
|
|
|
@ -28,7 +28,11 @@ add_task(async function() {
|
|||
"Refresh button is displayed after adding a watch expression"
|
||||
);
|
||||
|
||||
is(getWatchExpressionLabel(dbg, 1), "someVariable", "Watch expression was added");
|
||||
is(
|
||||
getWatchExpressionLabel(dbg, 1),
|
||||
"someVariable",
|
||||
"Watch expression was added"
|
||||
);
|
||||
is(
|
||||
getWatchExpressionValue(dbg, 1),
|
||||
"(unavailable)",
|
||||
|
@ -42,7 +46,11 @@ add_task(async function() {
|
|||
info("Switch back to the debugger");
|
||||
await dbg.toolbox.selectTool("jsdebugger");
|
||||
|
||||
is(getWatchExpressionLabel(dbg, 1), "someVariable", "Watch expression is still available");
|
||||
is(
|
||||
getWatchExpressionLabel(dbg, 1),
|
||||
"someVariable",
|
||||
"Watch expression is still available"
|
||||
);
|
||||
is(
|
||||
getWatchExpressionValue(dbg, 1),
|
||||
"(unavailable)",
|
||||
|
@ -57,7 +65,11 @@ add_task(async function() {
|
|||
await clickElement(dbg, "expressionRefresh");
|
||||
await refreshed;
|
||||
|
||||
is(getWatchExpressionLabel(dbg, 1), "someVariable", "Watch expression is still available");
|
||||
is(
|
||||
getWatchExpressionLabel(dbg, 1),
|
||||
"someVariable",
|
||||
"Watch expression is still available"
|
||||
);
|
||||
is(
|
||||
getWatchExpressionValue(dbg, 1),
|
||||
"1",
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_COM_URI =
|
||||
URL_ROOT_COM_SSL + "examples/doc_dbg-fission-frame-sources.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`;
|
||||
|
||||
add_task(async function() {
|
||||
// Load a test page with a remote frame:
|
||||
|
@ -16,7 +13,7 @@ add_task(async function() {
|
|||
"simple2.js"
|
||||
);
|
||||
const {
|
||||
selectors: { getSelectedSource, getIsPaused, getCurrentThread },
|
||||
selectors: { getSelectedSource },
|
||||
} = dbg;
|
||||
|
||||
// Add breakpoint within the iframe, which is hit early on load
|
||||
|
@ -26,10 +23,13 @@ add_task(async function() {
|
|||
const onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
info("Reload the page to hit the breakpoint on load");
|
||||
await reload(dbg);
|
||||
await onBreakpoint
|
||||
await onBreakpoint;
|
||||
await waitForSelectedSource(dbg, "simple2.js");
|
||||
|
||||
ok(getSelectedSource().url.includes("simple2.js"), "Selected source is simple2.js");
|
||||
ok(
|
||||
getSelectedSource().url.includes("simple2.js"),
|
||||
"Selected source is simple2.js"
|
||||
);
|
||||
assertPausedLocation(dbg);
|
||||
assertDebugLine(dbg, 7);
|
||||
|
||||
|
|
|
@ -2,16 +2,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_COM_URI = URL_ROOT_COM_SSL + "examples/doc_dbg-fission-pause-exceptions.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-pause-exceptions.html`;
|
||||
// Tests Pause on exceptions in remote iframes
|
||||
|
||||
add_task(async function() {
|
||||
// Load a test page with a remote iframe
|
||||
const dbg = await initDebuggerWithAbsoluteURL(TEST_COM_URI);
|
||||
|
||||
info("Test pause on exceptions ignoring caught exceptions")
|
||||
info("Test pause on exceptions ignoring caught exceptions");
|
||||
await togglePauseOnExceptions(dbg, true, false);
|
||||
|
||||
await reload(dbg);
|
||||
|
@ -22,7 +20,7 @@ add_task(async function() {
|
|||
|
||||
await resume(dbg);
|
||||
|
||||
info("Test pause on exceptions including caught exceptions")
|
||||
info("Test pause on exceptions including caught exceptions");
|
||||
await togglePauseOnExceptions(dbg, true, true);
|
||||
|
||||
await reload(dbg);
|
||||
|
@ -39,4 +37,3 @@ add_task(async function() {
|
|||
|
||||
await resume(dbg);
|
||||
});
|
||||
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_COM_URI =
|
||||
URL_ROOT_COM_SSL + "examples/doc_dbg-fission-frame-sources.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`;
|
||||
|
||||
add_task(async function() {
|
||||
// Simply load a test page with a remote frame and wait for both sources to
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
/* 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
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
const TEST_COM_URI =
|
||||
URL_ROOT_COM_SSL + "examples/doc_dbg-fission-frame-sources.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`;
|
||||
|
||||
// Testing project search for remote frames.
|
||||
add_task(async function () {
|
||||
add_task(async function() {
|
||||
// Load page and wait for sources. simple.js is loaded from
|
||||
// the top-level document in the dot com domain, while simple2.js
|
||||
// is loaded from the remote frame in the dot org domain
|
||||
|
@ -27,7 +28,7 @@ add_task(async function () {
|
|||
const fileResults = findAllElements(dbg, "projectSearchFileResults");
|
||||
const matches = findAllElements(dbg, "projectSearchExpandedResults");
|
||||
|
||||
is(fileResults.length, 2, "Two results found")
|
||||
is(fileResults.length, 2, "Two results found");
|
||||
is(matches.length, 6, "Total no of matches found");
|
||||
|
||||
// Asserts that we find a matches in the js file included in the top-level document
|
||||
|
@ -37,14 +38,17 @@ add_task(async function () {
|
|||
|
||||
function assertFileResult(fileMatched, noOfMatches) {
|
||||
// The results can be out of order so let find it from the collection
|
||||
const match = [...fileResults].find(result => result.querySelector(".file-path").innerText.includes(fileMatched));
|
||||
const match = [...fileResults].find(result =>
|
||||
result.querySelector(".file-path").innerText.includes(fileMatched)
|
||||
);
|
||||
|
||||
ok(match, `Matches were found in ${fileMatched} file.`);
|
||||
|
||||
const matchText = noOfMatches > 1 ? "matches" : "match";
|
||||
is(match.querySelector(".matches-summary").innerText.trim(),
|
||||
`(${noOfMatches} ${matchText})`,
|
||||
`${noOfMatches} ${matchText} were found in ${fileMatched} file.`);
|
||||
is(
|
||||
match.querySelector(".matches-summary").innerText.trim(),
|
||||
`(${noOfMatches} ${matchText})`,
|
||||
`${noOfMatches} ${matchText} were found in ${fileMatched} file.`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that we can set breakpoints in scripts that have been GCed.
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-gc-breakpoint-positions.html",
|
||||
"doc-gc-breakpoint-positions.html");
|
||||
const dbg = await initDebugger(
|
||||
"doc-gc-breakpoint-positions.html",
|
||||
"doc-gc-breakpoint-positions.html"
|
||||
);
|
||||
await selectSource(dbg, "doc-gc-breakpoint-positions.html");
|
||||
await addBreakpoint(dbg, "doc-gc-breakpoint-positions.html", 21);
|
||||
ok(true, "Added breakpoint at GC'ed script location");
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that we can set breakpoints in scripts that have been GCed.
|
||||
// Check that breakpoints can be set in GC'ed inline scripts, and in
|
||||
// generated and original sources of scripts with source maps specified either
|
||||
// inline or in their HTTP response headers.
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-gc-sources.html",
|
||||
"doc-gc-sources.html",
|
||||
"collected-bundle.js",
|
||||
"collected.js",
|
||||
"collected2.js");
|
||||
const dbg = await initDebugger(
|
||||
"doc-gc-sources.html",
|
||||
"doc-gc-sources.html",
|
||||
"collected-bundle.js",
|
||||
"collected.js",
|
||||
"collected2.js"
|
||||
);
|
||||
await selectSource(dbg, "doc-gc-sources.html");
|
||||
await addBreakpoint(dbg, "doc-gc-sources.html", 21);
|
||||
await selectSource(dbg, "collected-bundle.js");
|
||||
|
|
|
@ -9,7 +9,7 @@ add_task(async function() {
|
|||
await selectSource(dbg, "long.js");
|
||||
await waitForSelectedSource(dbg, "long.js");
|
||||
|
||||
info('Test opening');
|
||||
info("Test opening");
|
||||
pressKey(dbg, "goToLine");
|
||||
assertEnabled(dbg);
|
||||
is(
|
||||
|
@ -18,12 +18,12 @@ add_task(async function() {
|
|||
"The input area of 'go to line' box is focused"
|
||||
);
|
||||
|
||||
info('Test closing by the same keyboard shortcut');
|
||||
info("Test closing by the same keyboard shortcut");
|
||||
pressKey(dbg, "goToLine");
|
||||
assertDisabled(dbg);
|
||||
is(findElement(dbg, "searchField"), null, "The 'go to line' box is closed");
|
||||
|
||||
info('Test closing by escape');
|
||||
info("Test closing by escape");
|
||||
pressKey(dbg, "goToLine");
|
||||
assertEnabled(dbg);
|
||||
|
||||
|
@ -31,7 +31,7 @@ add_task(async function() {
|
|||
assertDisabled(dbg);
|
||||
is(findElement(dbg, "searchField"), null, "The 'go to line' box is closed");
|
||||
|
||||
info('Test going to the correct line');
|
||||
info("Test going to the correct line");
|
||||
pressKey(dbg, "goToLine");
|
||||
await waitForGoToLineBoxFocus(dbg);
|
||||
type(dbg, "66");
|
||||
|
|
|
@ -22,6 +22,8 @@ add_task(async function() {
|
|||
const calls = dbg.win.document.querySelectorAll(".highlight-function-calls");
|
||||
is(calls.length, 2);
|
||||
pressKey(dbg, "commandKeyUp");
|
||||
const nocalls = dbg.win.document.querySelectorAll(".highlight-function-calls");
|
||||
const nocalls = dbg.win.document.querySelectorAll(
|
||||
".highlight-function-calls"
|
||||
);
|
||||
is(nocalls.length, 0);
|
||||
});
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* Test loading inline scripts from cache:
|
||||
* - Load document with inline script
|
||||
|
|
|
@ -10,13 +10,17 @@ add_task(async function() {
|
|||
await selectSource(dbg, "exceptions.js");
|
||||
|
||||
info("Hovers over the inline exception mark text.");
|
||||
await assertPreviewTextValue(dbg, 81, 10, { text: 'TypeError: "abc".push is not a function' });
|
||||
await assertPreviewTextValue(dbg, 81, 10, {
|
||||
text: 'TypeError: "abc".push is not a function',
|
||||
});
|
||||
await closePreviewAtPos(dbg, 81, 10);
|
||||
|
||||
const excLineEls = findAllElementsWithSelector(dbg, ".line-exception");
|
||||
const excTextMarkEls = findAllElementsWithSelector(dbg, ".mark-text-exception");
|
||||
const excTextMarkEls = findAllElementsWithSelector(
|
||||
dbg,
|
||||
".mark-text-exception"
|
||||
);
|
||||
|
||||
is(excLineEls.length, 1, "The editor has one exception line");
|
||||
is(excTextMarkEls.length, 1, "One token is marked as an exception.");
|
||||
});
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ async function checkInlinePreview(dbg, fnName, inlinePreviews) {
|
|||
const values = findAllElements(dbg, "inlinePreviewValues");
|
||||
|
||||
inlinePreviews.forEach((inlinePreview, index) => {
|
||||
const { identifier, value, expandedValue } = inlinePreview;
|
||||
const { identifier, value } = inlinePreview;
|
||||
is(
|
||||
labels[index].innerText,
|
||||
identifier,
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that breakpoints work when set in inline scripts that do not start at column 0.
|
||||
|
||||
add_task(async function() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple2.js");
|
||||
let doc = dbg.win.document;
|
||||
const doc = dbg.win.document;
|
||||
|
||||
await selectSource(dbg, "simple2.js");
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ add_task(async function() {
|
|||
["vertical", "window:small"],
|
||||
["horizontal", "bottom"],
|
||||
["vertical", "right"],
|
||||
["horizontal", "window:big"]
|
||||
["horizontal", "window:big"],
|
||||
];
|
||||
|
||||
for (const layout of layouts) {
|
||||
|
@ -53,7 +53,7 @@ async function switchHost(dbg, hostType) {
|
|||
}
|
||||
|
||||
function resizeToolboxWindow(dbg, host) {
|
||||
const { panel, toolbox } = dbg;
|
||||
const { toolbox } = dbg;
|
||||
const sizeOption = host.split(":")[1];
|
||||
const win = toolbox.win.parent;
|
||||
|
||||
|
@ -66,9 +66,8 @@ function resizeToolboxWindow(dbg, host) {
|
|||
}
|
||||
|
||||
function resizeWindow(dbg, width) {
|
||||
const { panel, toolbox } = dbg;
|
||||
const { toolbox } = dbg;
|
||||
const win = toolbox.win.parent;
|
||||
const currentWidth = win.screen.width;
|
||||
win.resizeTo(width, window.screen.availHeight);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,20 +7,21 @@
|
|||
* It seems to cause different codepath compared to F5.
|
||||
*/
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-reload-link.html", "doc-reload-link.html");
|
||||
const {
|
||||
selectors: { getSelectedSource, getIsPaused, getCurrentThread },
|
||||
getState
|
||||
} = dbg;
|
||||
|
||||
const dbg = await initDebugger(
|
||||
"doc-reload-link.html",
|
||||
"doc-reload-link.html"
|
||||
);
|
||||
|
||||
info("Add a breakpoint that will be hit on reload");
|
||||
await addBreakpoint(dbg, "doc-reload-link.html", 3);
|
||||
|
||||
for(let i = 0; i < 5; i++) {
|
||||
let onReloaded = waitForReload(dbg.commands);
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const onReloaded = waitForReload(dbg.commands);
|
||||
|
||||
info("Reload via a link, this causes special race condition different from F5");
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
|
||||
info(
|
||||
"Reload via a link, this causes special race condition different from F5"
|
||||
);
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
||||
const reloadLink = content.document.querySelector("a");
|
||||
reloadLink.click();
|
||||
});
|
||||
|
@ -29,7 +30,7 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
|
||||
info("Check paused location\n");
|
||||
let source = findSource(dbg, "doc-reload-link.html");
|
||||
const source = findSource(dbg, "doc-reload-link.html");
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 3);
|
||||
|
||||
await resume(dbg);
|
||||
|
|
|
@ -23,7 +23,7 @@ add_task(async function() {
|
|||
await dbg.actions.addBreakpoint(
|
||||
getContext(dbg),
|
||||
{ line: 5, sourceId: source.id },
|
||||
{ logValue: "`value: ${JSON.stringify(test)}`", requiresMapping: true },
|
||||
{ logValue: "`value: ${JSON.stringify(test)}`", requiresMapping: true }
|
||||
);
|
||||
await waitForBreakpoint(dbg, "test.js", 5);
|
||||
|
||||
|
@ -33,6 +33,10 @@ add_task(async function() {
|
|||
|
||||
await hasConsoleMessage(dbg, "value:");
|
||||
const { value } = await findConsoleMessage(dbg, "value:");
|
||||
is(value, 'value: ["b (30)","a","b (5)","z"]', "Variables in logpoint expression should be mapped");
|
||||
is(
|
||||
value,
|
||||
'value: ["b (30)","a","b (5)","z"]',
|
||||
"Variables in logpoint expression should be mapped"
|
||||
);
|
||||
await resume(dbg);
|
||||
});
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
|
||||
add_task(async function() {
|
||||
Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
|
||||
const dbg = await initDebugger("doc-script-switching.html", "script-switching-01.js");
|
||||
const dbg = await initDebugger(
|
||||
"doc-script-switching.html",
|
||||
"script-switching-01.js"
|
||||
);
|
||||
|
||||
const source = findSource(dbg, "script-switching-01.js");
|
||||
await selectSource(dbg, "script-switching-01.js");
|
||||
|
|
|
@ -17,7 +17,7 @@ add_task(async function() {
|
|||
await testSimpleAndLog(dbg);
|
||||
|
||||
await testLogUpdates(dbg);
|
||||
})
|
||||
});
|
||||
|
||||
async function testSimpleAndLog(dbg) {
|
||||
info("Add a simple breakpoint");
|
||||
|
@ -29,14 +29,22 @@ async function testSimpleAndLog(dbg) {
|
|||
await assertLogBreakpoint(dbg, BREAKPOINT_LINE);
|
||||
|
||||
const bp = findBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE);
|
||||
is(bp.options.logValue, "`log point ${x}`", "log breakpoint value is correct");
|
||||
is(
|
||||
bp.options.logValue,
|
||||
"`log point ${x}`",
|
||||
"log breakpoint value is correct"
|
||||
);
|
||||
|
||||
info("Eval foo() and trigger the breakpoints. If this freeze here, it means that the log point has been ignored.");
|
||||
info(
|
||||
"Eval foo() and trigger the breakpoints. If this freeze here, it means that the log point has been ignored."
|
||||
);
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
||||
content.wrappedJSObject.foo(42);
|
||||
});
|
||||
|
||||
info("Wait for the log-point message. Only log-point breakpoint should work.");
|
||||
info(
|
||||
"Wait for the log-point message. Only log-point breakpoint should work."
|
||||
);
|
||||
await waitForMessage(dbg, "log point 42");
|
||||
|
||||
const source = findSource(dbg, "simple2.js");
|
||||
|
@ -58,7 +66,11 @@ async function testLogUpdates(dbg) {
|
|||
await assertLogBreakpoint(dbg, BREAKPOINT_LINE);
|
||||
|
||||
const bp2 = findBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE);
|
||||
is(bp2.options.logValue, "`log point` + ` edited`", "log breakpoint value is correct");
|
||||
is(
|
||||
bp2.options.logValue,
|
||||
"`log point` + ` edited`",
|
||||
"log breakpoint value is correct"
|
||||
);
|
||||
|
||||
info("Eval foo() and trigger the breakpoints");
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function() {
|
||||
|
|
|
@ -25,7 +25,16 @@ add_task(async function() {
|
|||
// When there is a function body, function lexical, and inner lexical scope,
|
||||
// the first two are merged together.
|
||||
await toggleScopeNode(dbg, 4);
|
||||
expectLabels(dbg, ["Block", "<this>", "z", "third", "arguments", "v", "x", "y"]);
|
||||
expectLabels(dbg, [
|
||||
"Block",
|
||||
"<this>",
|
||||
"z",
|
||||
"third",
|
||||
"arguments",
|
||||
"v",
|
||||
"x",
|
||||
"y",
|
||||
]);
|
||||
});
|
||||
|
||||
function getLabel(dbg, index) {
|
||||
|
@ -34,6 +43,10 @@ function getLabel(dbg, index) {
|
|||
|
||||
function expectLabels(dbg, array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
is(getLabel(dbg, i + 1), array[i], `Correct label ${array[i]} for index ${i + 1}`);
|
||||
is(
|
||||
getLabel(dbg, i + 1),
|
||||
array[i],
|
||||
`Correct label ${array[i]} for index ${i + 1}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ const SOURCES = [
|
|||
"simple2.js",
|
||||
"simple3.js",
|
||||
"long.js",
|
||||
"doc-scripts.html"
|
||||
"doc-scripts.html",
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -18,9 +18,8 @@ add_task(async function() {
|
|||
const dbg = await initDebugger("doc-script-switching.html");
|
||||
const {
|
||||
selectors: { getSelectedSource, getIsPaused, getCurrentThread },
|
||||
getState
|
||||
} = dbg;
|
||||
|
||||
|
||||
info("Pause in the first document");
|
||||
invokeInTab("firstCall");
|
||||
await waitForPaused(dbg);
|
||||
|
@ -33,21 +32,21 @@ add_task(async function() {
|
|||
await addBreakpoint(dbg, "simple1.js", 4);
|
||||
invokeInTab("main");
|
||||
await waitForPaused(dbg);
|
||||
let source = findSource(dbg, "simple1.js");
|
||||
const source = findSource(dbg, "simple1.js");
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 4);
|
||||
is(countSources(dbg), 5, "5 sources are loaded.");
|
||||
|
||||
await waitForRequestsToSettle(dbg);
|
||||
let onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
||||
await onBreakpoint
|
||||
await onBreakpoint;
|
||||
is(countSources(dbg), 5, "5 sources are loaded.");
|
||||
ok(!getIsPaused(getCurrentThread()), "Is not paused");
|
||||
|
||||
await waitForRequestsToSettle(dbg);
|
||||
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
||||
await onBreakpoint
|
||||
await onBreakpoint;
|
||||
is(countSources(dbg), 5, "5 sources are loaded.");
|
||||
|
||||
info("Test that the current selected source persists across reloads");
|
||||
|
@ -56,7 +55,7 @@ add_task(async function() {
|
|||
await waitForRequestsToSettle(dbg);
|
||||
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||
await reload(dbg, "long.js");
|
||||
await onBreakpoint
|
||||
await onBreakpoint;
|
||||
await waitForSelectedSource(dbg, "long.js");
|
||||
|
||||
ok(getSelectedSource().url.includes("long.js"), "Selected source is long.js");
|
||||
|
|
|
@ -11,37 +11,40 @@ add_task(async function() {
|
|||
bp1: {
|
||||
location: {
|
||||
sourceId: "",
|
||||
sourceUrl: EXAMPLE_URL + "nowhere2.js",
|
||||
sourceUrl: `${EXAMPLE_URL}nowhere2.js`,
|
||||
line: 5,
|
||||
column: 0
|
||||
column: 0,
|
||||
},
|
||||
generatedLocation: {
|
||||
sourceUrl: EXAMPLE_URL + "simple1.js",
|
||||
sourceUrl: `${EXAMPLE_URL}simple1.js`,
|
||||
line: 4,
|
||||
column: 0
|
||||
column: 0,
|
||||
},
|
||||
options: {},
|
||||
disabled: false
|
||||
disabled: false,
|
||||
},
|
||||
bp2: {
|
||||
location: {
|
||||
sourceId: "",
|
||||
sourceUrl: EXAMPLE_URL + "nowhere.js",
|
||||
sourceUrl: `${EXAMPLE_URL}nowhere.js`,
|
||||
line: 5,
|
||||
column: 0
|
||||
column: 0,
|
||||
},
|
||||
generatedLocation: {
|
||||
sourceUrl: EXAMPLE_URL + "simple3.js",
|
||||
sourceUrl: `${EXAMPLE_URL}simple3.js`,
|
||||
line: 2,
|
||||
column: 0
|
||||
column: 0,
|
||||
},
|
||||
options: {},
|
||||
disabled: false
|
||||
disabled: false,
|
||||
},
|
||||
};
|
||||
asyncStorage.setItem("debugger.pending-breakpoints", pending);
|
||||
|
||||
const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + "doc-scripts.html", "jsdebugger");
|
||||
const toolbox = await openNewTabAndToolbox(
|
||||
`${EXAMPLE_URL}doc-scripts.html`,
|
||||
"jsdebugger"
|
||||
);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
const onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT", 2);
|
||||
|
||||
|
@ -54,7 +57,10 @@ add_task(async function() {
|
|||
await onBreakpoint;
|
||||
|
||||
ok(true, "paused at unmapped breakpoint");
|
||||
await waitForState(dbg, state => dbg.selectors.getBreakpointCount(state) == 2);
|
||||
await waitForState(
|
||||
dbg,
|
||||
state => dbg.selectors.getBreakpointCount(state) == 2
|
||||
);
|
||||
ok(true, "unmapped breakpoints shown in UI");
|
||||
});
|
||||
|
||||
|
@ -70,28 +76,33 @@ add_task(async function() {
|
|||
sourceId: "",
|
||||
sourceUrl: "webpack:///entry.js",
|
||||
line: 15,
|
||||
column: 0
|
||||
column: 0,
|
||||
},
|
||||
generatedLocation: {
|
||||
sourceUrl: EXAMPLE_URL + "sourcemaps/bundle.js",
|
||||
sourceUrl: `${EXAMPLE_URL}sourcemaps/bundle.js`,
|
||||
line: 47,
|
||||
column: 16
|
||||
column: 16,
|
||||
},
|
||||
astLocation: {},
|
||||
options: {},
|
||||
disabled: false
|
||||
disabled: false,
|
||||
},
|
||||
};
|
||||
asyncStorage.setItem("debugger.pending-breakpoints", pending);
|
||||
|
||||
const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + "doc-sourcemaps.html", "jsdebugger");
|
||||
const toolbox = await openNewTabAndToolbox(
|
||||
`${EXAMPLE_URL}doc-sourcemaps.html`,
|
||||
"jsdebugger"
|
||||
);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
|
||||
await waitForState(dbg, state => {
|
||||
const bps = dbg.selectors.getBreakpointsList(state);
|
||||
return bps.length == 1
|
||||
&& bps[0].location.sourceUrl.includes("entry.js")
|
||||
&& bps[0].location.line == 15;
|
||||
return (
|
||||
bps.length == 1 &&
|
||||
bps[0].location.sourceUrl.includes("entry.js") &&
|
||||
bps[0].location.line == 15
|
||||
);
|
||||
});
|
||||
ok(true, "removed old breakpoint during sync");
|
||||
await waitForRequestsToSettle(dbg);
|
||||
|
|
|
@ -77,7 +77,3 @@ add_task(async function() {
|
|||
function getItems(dbg) {
|
||||
return findAllElements(dbg, "outlineItems");
|
||||
}
|
||||
|
||||
function getNthItem(dbg, index) {
|
||||
return findElement(dbg, "outlineItem", index);
|
||||
}
|
||||
|
|
|
@ -3,12 +3,8 @@
|
|||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Tests that the length of outline functions for original and pretty printed source matches
|
||||
add_task(async function () {
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple1.js");
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState
|
||||
} = dbg;
|
||||
|
||||
await selectSource(dbg, "simple1.js");
|
||||
findElementWithSelector(dbg, ".outline-tab").click();
|
||||
|
@ -19,13 +15,13 @@ add_task(async function () {
|
|||
await waitForElementWithSelector(dbg, ".outline-list");
|
||||
const prettySource = getItems(dbg);
|
||||
|
||||
is(originalSource.length, prettySource.length, "Length of outline functions for both prettyPrint and originalSource same");
|
||||
is(
|
||||
originalSource.length,
|
||||
prettySource.length,
|
||||
"Length of outline functions for both prettyPrint and originalSource same"
|
||||
);
|
||||
});
|
||||
|
||||
function getItems(dbg) {
|
||||
return findAllElements(dbg, "outlineItems");
|
||||
}
|
||||
|
||||
function getNthItem(dbg, index) {
|
||||
return findElement(dbg, "outlineItem", index);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
// Tests that outline panel can sort functions alphabetically.
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple1.js");
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState,
|
||||
} = dbg;
|
||||
|
||||
await selectSource(dbg, "simple1.js", 1);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html");
|
||||
const {
|
||||
selectors: { getIsWaitingOnBreak, getCurrentThread }
|
||||
selectors: { getIsWaitingOnBreak, getCurrentThread },
|
||||
} = dbg;
|
||||
|
||||
clickElement(dbg, "pause");
|
||||
|
|
|
@ -8,7 +8,7 @@ async function testCase(dbg, { name, steps }) {
|
|||
info(` ### Execute testCase "${name}"`);
|
||||
|
||||
const {
|
||||
selectors: { getTopFrame, getCurrentThread }
|
||||
selectors: { getTopFrame, getCurrentThread },
|
||||
} = dbg;
|
||||
const locations = [];
|
||||
|
||||
|
@ -50,18 +50,29 @@ add_task(async function test() {
|
|||
[11, 21],
|
||||
[12, 2],
|
||||
[12, 12],
|
||||
[13, 0]
|
||||
]
|
||||
[13, 0],
|
||||
],
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
name: "expressions",
|
||||
steps: [[40, 2], [41, 2], [42, 12], [43, 0]]
|
||||
steps: [
|
||||
[40, 2],
|
||||
[41, 2],
|
||||
[42, 12],
|
||||
[43, 0],
|
||||
],
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
name: "sequences",
|
||||
steps: [[23, 2], [25, 12], [29, 12], [34, 2], [37, 0]]
|
||||
steps: [
|
||||
[23, 2],
|
||||
[25, 12],
|
||||
[29, 12],
|
||||
[34, 2],
|
||||
[37, 0],
|
||||
],
|
||||
});
|
||||
|
||||
await testCase(dbg, {
|
||||
|
@ -74,8 +85,8 @@ add_task(async function test() {
|
|||
[19, 17],
|
||||
[19, 8],
|
||||
[19, 17],
|
||||
[19, 8]
|
||||
]
|
||||
[19, 8],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
// Tests the paused overlay in a remote frame
|
||||
|
||||
const TEST_COM_URI =
|
||||
URL_ROOT_COM_SSL + "examples/doc_dbg-fission-frame-sources.html";
|
||||
const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`;
|
||||
|
||||
add_task(async function() {
|
||||
info("Load a test page with a remote frame");
|
||||
|
@ -17,7 +16,6 @@ add_task(async function() {
|
|||
);
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState,
|
||||
commands,
|
||||
} = dbg;
|
||||
|
||||
|
@ -50,9 +48,7 @@ add_task(async function() {
|
|||
}
|
||||
|
||||
info("Check that the paused overlay is displayed");
|
||||
await waitFor(
|
||||
async () => await highlighterTestFront.isPausedDebuggerOverlayVisible()
|
||||
);
|
||||
await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible());
|
||||
ok(true, "Paused debugger overlay is visible");
|
||||
|
||||
ok(
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html");
|
||||
const {
|
||||
selectors: { getSelectedSource },
|
||||
getState,
|
||||
} = dbg;
|
||||
|
||||
// Sanity check
|
||||
const highlighterTestFront = await getHighlighterTestFront(dbg.toolbox);
|
||||
|
@ -25,12 +21,10 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
|
||||
info("Check that the paused overlay is displayed");
|
||||
await waitFor(
|
||||
async () => await highlighterTestFront.isPausedDebuggerOverlayVisible()
|
||||
);
|
||||
await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible());
|
||||
ok(true, "Paused debugger overlay is visible");
|
||||
|
||||
let pauseLine = getVisibleSelectedFrameLine(dbg);
|
||||
const pauseLine = getVisibleSelectedFrameLine(dbg);
|
||||
is(pauseLine, 2, "We're paused at the expected location");
|
||||
|
||||
info("Test clicking the step over button");
|
||||
|
@ -61,13 +55,10 @@ add_task(async function() {
|
|||
"Check that the highlighter is removed when clicking on the debugger resume button"
|
||||
);
|
||||
invokeInTab("doEval");
|
||||
await waitFor(
|
||||
async () => await highlighterTestFront.isPausedDebuggerOverlayVisible()
|
||||
);
|
||||
await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible());
|
||||
ok(true, "Paused debugger overlay is visible again");
|
||||
|
||||
info("Click debugger UI resume button");
|
||||
debugger;
|
||||
const resumeButton = await waitFor(() => findElement(dbg, "resume"));
|
||||
resumeButton.click();
|
||||
await waitFor(async () => {
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
// are properly removed when the user deletes them on either the generated or original files.
|
||||
|
||||
add_task(async function() {
|
||||
info("Test removing the breakpoint from the minified file (generated source) works");
|
||||
info(
|
||||
"Test removing the breakpoint from the minified file (generated source) works"
|
||||
);
|
||||
|
||||
const dbg = await initDebugger("doc-pretty.html", "pretty.js");
|
||||
|
||||
|
@ -16,12 +18,16 @@ add_task(async function() {
|
|||
|
||||
await addBreakpointToPrettyPrintedFile(dbg);
|
||||
|
||||
info(`Close the pretty-printed source, so it is not automatically reopened on reload`);
|
||||
info(
|
||||
`Close the pretty-printed source, so it is not automatically reopened on reload`
|
||||
);
|
||||
await closeTab(dbg, "pretty.js:formatted");
|
||||
|
||||
await waitForSelectedSource(dbg, "pretty.js");
|
||||
|
||||
info("Assert that a equivalent breakpoint was set in pretty.js (generated source)");
|
||||
info(
|
||||
"Assert that a equivalent breakpoint was set in pretty.js (generated source)"
|
||||
);
|
||||
await assertBreakpoint(dbg, 4);
|
||||
|
||||
info(`Remove the breakpoint from pretty.js (generated source)`);
|
||||
|
@ -33,7 +39,9 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
add_task(async function() {
|
||||
info("Test removing the breakpoint from the pretty printed (original source) works");
|
||||
info(
|
||||
"Test removing the breakpoint from the pretty printed (original source) works"
|
||||
);
|
||||
|
||||
const dbg = await initDebugger("doc-pretty.html", "pretty.js");
|
||||
|
||||
|
@ -43,11 +51,11 @@ add_task(async function() {
|
|||
|
||||
await addBreakpointToPrettyPrintedFile(dbg);
|
||||
|
||||
info("Check that breakpoint gets added to pretty.js (generated source)")
|
||||
info("Check that breakpoint gets added to pretty.js (generated source)");
|
||||
await selectSource(dbg, "pretty.js");
|
||||
await assertBreakpoint(dbg, 4);
|
||||
|
||||
info("Close the pretty.js (generated source)")
|
||||
info("Close the pretty.js (generated source)");
|
||||
await closeTab(dbg, "pretty.js");
|
||||
|
||||
await waitForSelectedSource(dbg, "pretty.js:formatted");
|
||||
|
@ -60,7 +68,6 @@ add_task(async function() {
|
|||
await reloadAndCheckNoBreakpointExists(dbg);
|
||||
});
|
||||
|
||||
|
||||
async function addBreakpointToPrettyPrintedFile(dbg) {
|
||||
// This breakpoint would be set before the debugger statement
|
||||
// and should be hit first.
|
||||
|
@ -81,13 +88,17 @@ async function reloadAndCheckNoBreakpointExists(dbg) {
|
|||
|
||||
const sourcePretty = findSource(dbg, "pretty.js:formatted");
|
||||
|
||||
info("Assert pause at the debugger statement in pretty.js:formatted (original source) and not the removed breakpoint");
|
||||
info(
|
||||
"Assert pause at the debugger statement in pretty.js:formatted (original source) and not the removed breakpoint"
|
||||
);
|
||||
assertPausedAtSourceAndLine(dbg, sourcePretty.id, 8);
|
||||
|
||||
await selectSource(dbg, "pretty.js");
|
||||
const source = findSource(dbg, "pretty.js");
|
||||
|
||||
info("Assert pause at the debugger statement in pretty.js (generated source) and not the removed breakpoint");
|
||||
info(
|
||||
"Assert pause at the debugger statement in pretty.js (generated source) and not the removed breakpoint"
|
||||
);
|
||||
assertPausedAtSourceAndLine(dbg, source.id, 6);
|
||||
|
||||
info(`Confirm that pretty.js:formatted does not have any breakpoints`);
|
||||
|
@ -95,4 +106,3 @@ async function reloadAndCheckNoBreakpointExists(dbg) {
|
|||
|
||||
await resume(dbg);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,11 @@ add_task(async function() {
|
|||
|
||||
await assertBreakpointsInNonPrettyAndPrettySources(dbg);
|
||||
|
||||
is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint still exists after pause ");
|
||||
is(
|
||||
dbg.selectors.getBreakpointCount(),
|
||||
1,
|
||||
"Only one breakpoint still exists after pause "
|
||||
);
|
||||
|
||||
await resume(dbg);
|
||||
});
|
||||
|
@ -51,7 +55,11 @@ add_task(async function() {
|
|||
|
||||
await assertBreakpointsInNonPrettyAndPrettySources(dbg);
|
||||
|
||||
is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint still exists after reload and pause ");
|
||||
is(
|
||||
dbg.selectors.getBreakpointCount(),
|
||||
1,
|
||||
"Only one breakpoint still exists after reload and pause "
|
||||
);
|
||||
});
|
||||
|
||||
// Test that breakpoints appear and work when set in the minified source
|
||||
|
@ -60,12 +68,14 @@ add_task(async function() {
|
|||
|
||||
await selectSource(dbg, "pretty.js");
|
||||
|
||||
info ("Add breakpoint to pretty.js (generated source)");
|
||||
info("Add breakpoint to pretty.js (generated source)");
|
||||
await addBreakpoint(dbg, "pretty.js", 4, 7);
|
||||
|
||||
await prettyPrint(dbg);
|
||||
|
||||
info("Check that equivalent breakpoint is added to pretty.js:formatted (original source)");
|
||||
info(
|
||||
"Check that equivalent breakpoint is added to pretty.js:formatted (original source)"
|
||||
);
|
||||
await selectSource(dbg, "pretty.js:formatted");
|
||||
await assertBreakpoint(dbg, 5);
|
||||
|
||||
|
@ -80,13 +90,17 @@ add_task(async function() {
|
|||
|
||||
await assertBreakpointsInNonPrettyAndPrettySources(dbg);
|
||||
|
||||
is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint still exists after reload and pause ");
|
||||
is(
|
||||
dbg.selectors.getBreakpointCount(),
|
||||
1,
|
||||
"Only one breakpoint still exists after reload and pause "
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
async function assertBreakpointsInNonPrettyAndPrettySources(dbg) {
|
||||
info("Asserts breakpoint pause and display on the correct line in the pretty printed source");
|
||||
info(
|
||||
"Asserts breakpoint pause and display on the correct line in the pretty printed source"
|
||||
);
|
||||
const prettyPrintedSource = findSource(dbg, "pretty.js:formatted");
|
||||
await assertPausedAtSourceAndLine(dbg, prettyPrintedSource.id, 5);
|
||||
await assertBreakpoint(dbg, 5);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче