зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1461970 - Remove tests using helpers.openToolbar. r=jryans
MozReview-Commit-ID: JLz99KdTZFH --HG-- extra : rebase_source : 2977d6760faabc0d7d5e583bd79b37c04da64bda
This commit is contained in:
Родитель
6d5ecd386d
Коммит
86d42e4a61
|
@ -67,7 +67,6 @@ support-files =
|
|||
doc_closures.html
|
||||
doc_closure-optimized-out.html
|
||||
doc_cmd-break.html
|
||||
doc_cmd-dbg.html
|
||||
doc_breakpoint-move.html
|
||||
doc_conditional-breakpoints.html
|
||||
doc_domnode-variables.html
|
||||
|
@ -251,12 +250,8 @@ skip-if = true # Bug 1044985 (racy test)
|
|||
[browser_dbg_closure-inspection.js]
|
||||
uses-unsafe-cpows = true
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_cmd-blackbox.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_cmd-break.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_cmd-dbg.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_conditional-breakpoints-01.js]
|
||||
uses-unsafe-cpows = true
|
||||
skip-if = e10s && debug
|
||||
|
|
|
@ -67,7 +67,6 @@ support-files =
|
|||
doc_closures.html
|
||||
doc_closure-optimized-out.html
|
||||
doc_cmd-break.html
|
||||
doc_cmd-dbg.html
|
||||
doc_breakpoint-move.html
|
||||
doc_conditional-breakpoints.html
|
||||
doc_domnode-variables.html
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the 'dbg blackbox' and 'dbg unblackbox' commands work as
|
||||
* they should.
|
||||
*/
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
const BLACKBOXONE_URL = EXAMPLE_URL + "code_blackboxing_one.js";
|
||||
const BLACKBOXTWO_URL = EXAMPLE_URL + "code_blackboxing_two.js";
|
||||
const BLACKBOXTHREE_URL = EXAMPLE_URL + "code_blackboxing_three.js";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(spawnTest).then(finish, helpers.handleError);
|
||||
}
|
||||
|
||||
function* spawnTest() {
|
||||
let options = yield helpers.openTab(TEST_URL);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
let toolbox = yield gDevTools.showToolbox(options.target, "jsdebugger");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let constants = panel.panelWin.require("./content/constants");
|
||||
|
||||
yield waitForDebuggerEvents(panel, panel.panelWin.EVENTS.SOURCE_SHOWN);
|
||||
|
||||
function cmd(aTyped, aEventRepeat = 1, aOutput = "") {
|
||||
return promise.all([
|
||||
waitForDispatch(panel, constants.BLACKBOX, aEventRepeat),
|
||||
helpers.audit(options, [{ setup: aTyped, output: aOutput, exec: {} }])
|
||||
]);
|
||||
}
|
||||
|
||||
// test Black-Box Source
|
||||
yield cmd("dbg blackbox " + BLACKBOXME_URL);
|
||||
|
||||
let bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(bbButton.checked,
|
||||
"Should be able to black box a specific source.");
|
||||
|
||||
// test Un-Black-Box Source
|
||||
yield cmd("dbg unblackbox " + BLACKBOXME_URL);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"Should be able to stop black boxing a specific source.");
|
||||
|
||||
// test Black-Box Glob
|
||||
yield cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackboxme should not be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_one should not be black boxed because it doesn't match the glob.");
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_two should be black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_three should be black boxed because it matches the glob.");
|
||||
|
||||
// test Un-Black-Box Glob
|
||||
yield cmd("dbg unblackbox --glob *blackboxing_t*.js", 2);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_two should be un-black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_three should be un-black boxed because it matches the glob.");
|
||||
|
||||
// test Black-Box Invert
|
||||
yield cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackboxme should be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_one should be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, TEST_URL);
|
||||
ok(bbButton.checked,
|
||||
"TEST_URL should be black boxed because it doesn't match the glob.");
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_two should not be black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_three should not be black boxed because it matches the glob.");
|
||||
|
||||
// test Un-Black-Box Invert
|
||||
yield cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackboxme should be un-black boxed because it does not match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_one should be un-black boxed because it does not match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, TEST_URL);
|
||||
ok(!bbButton.checked,
|
||||
"TEST_URL should be un-black boxed because it doesn't match the glob.");
|
||||
|
||||
yield teardown(panel, { noTabRemoval: true });
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the debugger commands work as they should.
|
||||
*/
|
||||
|
||||
const TEST_URI = EXAMPLE_URL + "doc_cmd-dbg.html";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(function* () {
|
||||
let options = yield helpers.openTab(TEST_URI);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg open",
|
||||
exec: { output: "" }
|
||||
}]);
|
||||
|
||||
let [gTab, gDebuggee, gPanel] = yield initDebugger(gBrowser.selectedTab);
|
||||
let gDebugger = gPanel.panelWin;
|
||||
let gThreadClient = gDebugger.gThreadClient;
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg list",
|
||||
exec: { output: /doc_cmd-dbg.html/ }
|
||||
}]);
|
||||
|
||||
let button = gDebuggee.document.querySelector("input[type=button]");
|
||||
let output = gDebuggee.document.querySelector("input[type=text]");
|
||||
|
||||
let cmd = function (aTyped, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
helpers.audit(options, [{ setup: aTyped, exec: { output: "" } }])
|
||||
]);
|
||||
};
|
||||
|
||||
let click = function (aElement, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
executeSoon(() => EventUtils.sendMouseEvent({ type: "click" }, aElement, gDebuggee))
|
||||
]);
|
||||
};
|
||||
|
||||
yield cmd("dbg interrupt", "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused.");
|
||||
|
||||
yield cmd("dbg continue", "resumed");
|
||||
isnot(gThreadClient.state, "paused", "Debugger has continued.");
|
||||
|
||||
yield click(button, "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused again.");
|
||||
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
is(output.value, "step in", "Debugger stepped in.");
|
||||
|
||||
yield cmd("dbg step over", "paused");
|
||||
is(output.value, "step over", "Debugger stepped over.");
|
||||
|
||||
yield cmd("dbg step out", "paused");
|
||||
is(output.value, "step out", "Debugger stepped out.");
|
||||
|
||||
yield cmd("dbg continue", "paused");
|
||||
is(output.value, "dbg continue", "Debugger continued.");
|
||||
|
||||
let closeDebugger = function () {
|
||||
let deferred = promise.defer();
|
||||
|
||||
helpers.audit(options, [{
|
||||
setup: "dbg close",
|
||||
exec: { output: "" }
|
||||
}])
|
||||
.then(() => {
|
||||
let toolbox = gDevTools.getToolbox(options.target);
|
||||
if (!toolbox) {
|
||||
ok(true, "Debugger is closed.");
|
||||
deferred.resolve();
|
||||
} else {
|
||||
toolbox.on("destroyed", () => {
|
||||
ok(true, "Debugger just closed.");
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
// We close the debugger twice to ensure 'dbg close' doesn't error when
|
||||
// toolbox is already closed. See bug 884638 for more info.
|
||||
yield closeDebugger();
|
||||
yield closeDebugger();
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
|
||||
}).then(finish, helpers.handleError);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="text" value=""/>
|
||||
<input type="button" value="Click me!" onclick="test()"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
let output = document.querySelector("input");
|
||||
output.value = "";
|
||||
|
||||
function test() {
|
||||
debugger;
|
||||
stepIntoMe(); // step in
|
||||
|
||||
output.value = "dbg continue";
|
||||
debugger;
|
||||
}
|
||||
|
||||
function stepIntoMe() {
|
||||
output.value = "step in"; // step in
|
||||
stepOverMe(); // step over
|
||||
let x = 0; // step out
|
||||
output.value = "step out";
|
||||
}
|
||||
|
||||
function stepOverMe() {
|
||||
output.value = "step over";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -3,7 +3,6 @@ tags = devtools
|
|||
subsuite = devtools
|
||||
support-files =
|
||||
autocomplete.html
|
||||
browser_styleeditor_cmd_edit.html
|
||||
bug_1405342_serviceworker_iframes.html
|
||||
four.html
|
||||
head.js
|
||||
|
@ -79,7 +78,6 @@ support-files =
|
|||
[browser_styleeditor_bug_851132_middle_click.js]
|
||||
[browser_styleeditor_bug_870339.js]
|
||||
[browser_styleeditor_bug_1405342_serviceworker_iframes.js]
|
||||
[browser_styleeditor_cmd_edit.js]
|
||||
[browser_styleeditor_enabled.js]
|
||||
[browser_styleeditor_fetch-from-netmonitor.js]
|
||||
[browser_styleeditor_filesave.js]
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Resources</title>
|
||||
<script type="text/javascript" id="script1">
|
||||
"use strict";
|
||||
|
||||
window.addEventListener("load", function onload() {
|
||||
let pid = document.getElementById("pid");
|
||||
let div = document.createElement("div");
|
||||
div.id = "divid";
|
||||
div.classList.add("divclass");
|
||||
div.appendChild(document.createTextNode("div"));
|
||||
div.setAttribute("data-a1", "div");
|
||||
pid.parentNode.appendChild(div);
|
||||
});
|
||||
</script>
|
||||
<script src="resources_inpage.jsi"></script>
|
||||
<link rel="stylesheet" type="text/css" href="resources_inpage1.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="resources_inpage2.css"/>
|
||||
<style type="text/css">
|
||||
p { color: #800; }
|
||||
div { color: #008; }
|
||||
h4 { color: #080; }
|
||||
h3 { color: #880; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css" id=style2>
|
||||
.pclass { background-color: #FEE; }
|
||||
.divclass { background-color: #EEF; }
|
||||
.h4class { background-color: #EFE; }
|
||||
.h3class { background-color: #FFE; }
|
||||
</style>
|
||||
|
||||
<p class="pclass" id="pid" data-a1="p">paragraph</p>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
let pid = document.getElementById("pid");
|
||||
let h4 = document.createElement("h4");
|
||||
h4.id = "h4id";
|
||||
h4.classList.add("h4class");
|
||||
h4.appendChild(document.createTextNode("h4"));
|
||||
h4.setAttribute("data-a1", "h4");
|
||||
pid.parentNode.appendChild(h4);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,215 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that the edit command works
|
||||
|
||||
// Import the GCLI test helper
|
||||
/* import-globals-from ../../commandline/test/helpers.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/commandline/test/helpers.js",
|
||||
this);
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/styleeditor/" +
|
||||
"test/browser_styleeditor_cmd_edit.html";
|
||||
|
||||
add_task(async function() {
|
||||
let options = await helpers.openTab(TEST_URI);
|
||||
await helpers.openToolbar(options);
|
||||
|
||||
await helpers.audit(options, [
|
||||
{
|
||||
setup: "edit",
|
||||
check: {
|
||||
input: "edit",
|
||||
hints: " <resource> [line]",
|
||||
markup: "VVVV",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: { status: "INCOMPLETE" },
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit i",
|
||||
check: {
|
||||
input: "edit i",
|
||||
hints: "nline-css [line]",
|
||||
markup: "VVVVVI",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: { arg: " i", status: "INCOMPLETE" },
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit c",
|
||||
check: {
|
||||
input: "edit c",
|
||||
hints: "ss#style2 [line]",
|
||||
markup: "VVVVVI",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: { arg: " c", status: "INCOMPLETE" },
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit http",
|
||||
check: {
|
||||
input: "edit http",
|
||||
hints: "://example.com/browser/devtools/client/styleeditor/test/" +
|
||||
"resources_inpage1.css [line]",
|
||||
markup: "VVVVVIIII",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: {
|
||||
arg: " http",
|
||||
status: "INCOMPLETE",
|
||||
message: "Value required for \u2018resource\u2019."
|
||||
},
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit page1",
|
||||
check: {
|
||||
input: "edit page1",
|
||||
hints: " [line] -> http://example.com/browser/devtools/client/" +
|
||||
"styleeditor/test/resources_inpage1.css",
|
||||
markup: "VVVVVIIIII",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: {
|
||||
arg: " page1",
|
||||
status: "INCOMPLETE",
|
||||
message: "Value required for \u2018resource\u2019."
|
||||
},
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit page2",
|
||||
check: {
|
||||
input: "edit page2",
|
||||
hints: " [line] -> http://example.com/browser/devtools/client/" +
|
||||
"styleeditor/test/resources_inpage2.css",
|
||||
markup: "VVVVVIIIII",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: {
|
||||
arg: " page2",
|
||||
status: "INCOMPLETE",
|
||||
message: "Value required for \u2018resource\u2019."
|
||||
},
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit stylez",
|
||||
check: {
|
||||
input: "edit stylez",
|
||||
hints: " [line]",
|
||||
markup: "VVVVVEEEEEE",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: {
|
||||
arg: " stylez",
|
||||
status: "ERROR", message: "Can\u2019t use \u2018stylez\u2019." },
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit css#style2",
|
||||
check: {
|
||||
input: "edit css#style2",
|
||||
hints: " [line]",
|
||||
markup: "VVVVVVVVVVVVVVV",
|
||||
status: "VALID",
|
||||
args: {
|
||||
resource: { arg: " css#style2", status: "VALID", message: "" },
|
||||
line: { status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit css#style2 5",
|
||||
check: {
|
||||
input: "edit css#style2 5",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVVVVVVVVV",
|
||||
status: "VALID",
|
||||
args: {
|
||||
resource: { arg: " css#style2", status: "VALID", message: "" },
|
||||
line: { value: 5, arg: " 5", status: "VALID" },
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit css#style2 0",
|
||||
check: {
|
||||
input: "edit css#style2 0",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVVVVVVVVE",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: { arg: " css#style2", status: "VALID", message: "" },
|
||||
line: {
|
||||
arg: " 0",
|
||||
status: "ERROR",
|
||||
message: "0 is smaller than minimum allowed: 1."
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: "edit css#style2 -1",
|
||||
check: {
|
||||
input: "edit css#style2 -1",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVVVVVVVVEE",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
resource: { arg: " css#style2", status: "VALID", message: "" },
|
||||
line: {
|
||||
arg: " -1",
|
||||
status: "ERROR",
|
||||
message: "-1 is smaller than minimum allowed: 1."
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
]);
|
||||
|
||||
let toolbox = gDevTools.getToolbox(options.target);
|
||||
ok(toolbox == null, "toolbox is closed");
|
||||
|
||||
await helpers.audit(options, [
|
||||
{
|
||||
setup: "edit css#style2",
|
||||
check: {
|
||||
input: "edit css#style2",
|
||||
},
|
||||
exec: { output: "" }
|
||||
},
|
||||
]);
|
||||
|
||||
toolbox = gDevTools.getToolbox(options.target);
|
||||
ok(toolbox != null, "toolbox is open");
|
||||
|
||||
let styleEditor = toolbox.getCurrentPanel();
|
||||
ok(typeof styleEditor.selectStyleSheet === "function", "styleeditor is open");
|
||||
|
||||
await toolbox.destroy();
|
||||
|
||||
await helpers.closeToolbar(options);
|
||||
await helpers.closeTab(options);
|
||||
});
|
Загрузка…
Ссылка в новой задаче