Merge autoland to mozilla-central. a=merge

This commit is contained in:
Marian-Vasile Laza 2022-02-23 19:49:43 -08:00
Родитель 8efeb8af3a cdc4e9371e
Коммит acfb3e797d
397 изменённых файлов: 7045 добавлений и 4276 удалений

Просмотреть файл

@ -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/

Просмотреть файл

@ -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);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше