зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1485400 - Remove ')' from merge conflict. a=bustage-fix
This commit is contained in:
Коммит
973b725f51
|
@ -95,6 +95,7 @@ export default class AddressForm extends PaymentStateSubscriberMixin(PaymentRequ
|
|||
// validity will be updated before our handlers get the event
|
||||
this.form.addEventListener("input", this);
|
||||
this.form.addEventListener("invalid", this);
|
||||
this.form.addEventListener("change", this);
|
||||
|
||||
this.body.appendChild(this.persistCheckbox);
|
||||
this.body.appendChild(this.genericErrorText);
|
||||
|
@ -210,6 +211,10 @@ export default class AddressForm extends PaymentStateSubscriberMixin(PaymentRequ
|
|||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "change": {
|
||||
this.updateSaveButtonState();
|
||||
break;
|
||||
}
|
||||
case "click": {
|
||||
this.onClick(event);
|
||||
break;
|
||||
|
|
|
@ -141,6 +141,11 @@ add_task(async function test_saveButton() {
|
|||
is(form.querySelectorAll(":-moz-ui-invalid").length, 0, "Check no fields visibly invalid");
|
||||
ok(!form.saveButton.disabled, "Save button is enabled after re-filling street-address");
|
||||
|
||||
fillField(form.form.querySelector("#country"), "CA");
|
||||
ok(form.saveButton.disabled, "Save button is disabled after changing the country to Canada");
|
||||
fillField(form.form.querySelector("#country"), "US");
|
||||
ok(!form.saveButton.disabled, "Save button is enabled after changing the country to US");
|
||||
|
||||
let messagePromise = promiseContentToChromeMessage("updateAutofillRecord");
|
||||
is(form.saveButton.textContent, "Add", "Check label");
|
||||
form.saveButton.scrollIntoView();
|
||||
|
|
|
@ -116,6 +116,17 @@ add_task(async function test_saveButton() {
|
|||
ok(!form.saveButton.disabled,
|
||||
"Save button should be enabled since the required fields are filled");
|
||||
|
||||
fillField(form.form.querySelector("#cc-exp-month"), "");
|
||||
fillField(form.form.querySelector("#cc-exp-year"), "");
|
||||
form.saveButton.focus();
|
||||
ok(form.saveButton.disabled,
|
||||
"Save button should be disabled since the required fields are empty");
|
||||
fillField(form.form.querySelector("#cc-exp-month"), "11");
|
||||
fillField(form.form.querySelector("#cc-exp-year"), year);
|
||||
form.saveButton.focus();
|
||||
ok(!form.saveButton.disabled,
|
||||
"Save button should be enabled since the required fields are filled again");
|
||||
|
||||
info("blanking the cc-number field");
|
||||
fillField(form.form.querySelector("#cc-number"), "");
|
||||
ok(form.saveButton.disabled, "Save button is disabled after blanking cc-number");
|
||||
|
@ -381,6 +392,8 @@ add_task(async function test_field_validity_updates() {
|
|||
|
||||
let ccNumber = form.form.querySelector("#cc-number");
|
||||
let nameInput = form.form.querySelector("#cc-name");
|
||||
let monthInput = form.form.querySelector("#cc-exp-month");
|
||||
let yearInput = form.form.querySelector("#cc-exp-year");
|
||||
|
||||
info("test with valid cc-number but missing cc-name");
|
||||
fillField(ccNumber, "4111111111111111");
|
||||
|
@ -388,10 +401,15 @@ add_task(async function test_field_validity_updates() {
|
|||
ok(!nameInput.checkValidity(), "cc-name field is invalid when empty");
|
||||
ok(form.saveButton.disabled, "Save button should be disabled with incomplete input");
|
||||
|
||||
info("correct by adding cc-name value");
|
||||
info("correct by adding cc-name and expiration values");
|
||||
fillField(nameInput, "First");
|
||||
fillField(monthInput, "11");
|
||||
let year = (new Date()).getFullYear().toString();
|
||||
fillField(yearInput, year);
|
||||
ok(ccNumber.checkValidity(), "cc-number field is valid with good input");
|
||||
ok(nameInput.checkValidity(), "cc-name field is valid with a value");
|
||||
ok(monthInput.checkValidity(), "cc-exp-month field is valid with a value");
|
||||
ok(yearInput.checkValidity(), "cc-exp-year field is valid with a value");
|
||||
ok(!form.saveButton.disabled, "Save button should not be disabled with good input");
|
||||
|
||||
info("edit to make the cc-number invalid");
|
||||
|
|
|
@ -1553,14 +1553,23 @@ var gMainPane = {
|
|||
if (this._filter.value)
|
||||
visibleTypes = visibleTypes.filter(this._matchesFilter, this);
|
||||
|
||||
for (let visibleType of visibleTypes) {
|
||||
let item = new HandlerListItem(visibleType);
|
||||
item.connectAndAppendToList(this._list);
|
||||
|
||||
if (visibleType.type === lastSelectedType) {
|
||||
this._list.selectedItem = item.node;
|
||||
let items = visibleTypes.map(visibleType => new HandlerListItem(visibleType));
|
||||
let itemsFragment = document.createDocumentFragment();
|
||||
let lastSelectedItem;
|
||||
for (let item of items) {
|
||||
item.createNode(itemsFragment);
|
||||
if (item.handlerInfoWrapper.type == lastSelectedType) {
|
||||
lastSelectedItem = item;
|
||||
}
|
||||
}
|
||||
this._list.appendChild(itemsFragment);
|
||||
for (let item of items) {
|
||||
item.setupNode();
|
||||
}
|
||||
|
||||
if (lastSelectedItem) {
|
||||
this._list.selectedItem = lastSelectedItem.node;
|
||||
}
|
||||
},
|
||||
|
||||
_matchesFilter(aType) {
|
||||
|
@ -2496,11 +2505,13 @@ class HandlerListItem {
|
|||
}
|
||||
}
|
||||
|
||||
connectAndAppendToList(list) {
|
||||
createNode(list) {
|
||||
list.appendChild(document.importNode(gHandlerListItemFragment, true));
|
||||
this.node = list.lastChild;
|
||||
gNodeToObjectMap.set(this.node, this);
|
||||
}
|
||||
|
||||
setupNode() {
|
||||
this.node.querySelector(".actionsMenu").addEventListener("command",
|
||||
event => gMainPane.onSelectAction(event.originalTarget));
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<span data-localization="cardNumber" class="label-text"/>
|
||||
</label>
|
||||
<label id="cc-exp-month-container" class="container">
|
||||
<select id="cc-exp-month">
|
||||
<select id="cc-exp-month" required="required">
|
||||
<option/>
|
||||
<option value="1">01</option>
|
||||
<option value="2">02</option>
|
||||
|
@ -46,7 +46,7 @@
|
|||
<span data-localization="cardExpiresMonth" class="label-text"/>
|
||||
</label>
|
||||
<label id="cc-exp-year-container" class="container">
|
||||
<select id="cc-exp-year">
|
||||
<select id="cc-exp-year" required="required">
|
||||
<option/>
|
||||
</select>
|
||||
<span data-localization="cardExpiresYear" class="label-text"/>
|
||||
|
|
|
@ -84,7 +84,7 @@ connection-proxy-socks-remote-dns =
|
|||
|
||||
connection-dns-over-https =
|
||||
.label = Enable DNS over HTTPS
|
||||
.accesskey = H
|
||||
.accesskey = b
|
||||
|
||||
connection-dns-over-https-url = URL
|
||||
.accesskey = U
|
||||
|
|
|
@ -32,7 +32,7 @@ export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip"
|
|||
export BINDGEN_CFLAGS="$FLAGS"
|
||||
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-
|
||||
export DSYMUTIL=$topsrcdir/build/macosx/llvm-dsymutil
|
||||
mk_add_options "export REAL_DSYMUTIL=$topsrcdir/llvm-dsymutil/bin/llvm-dsymutil"
|
||||
mk_add_options "export REAL_DSYMUTIL=$topsrcdir/llvm-dsymutil/bin/dsymutil"
|
||||
export MKFSHFS=$topsrcdir/hfsplus-tools/newfs_hfs
|
||||
export DMG_TOOL=$topsrcdir/dmg/dmg
|
||||
export HFS_TOOL=$topsrcdir/dmg/hfsplus
|
||||
|
|
|
@ -3555,14 +3555,16 @@ public:
|
|||
--mIgnoreOpensDuringUnloadCounter;
|
||||
}
|
||||
|
||||
void IncrementTrackerCount(bool aIsTrackerBlocked)
|
||||
void IncrementTrackerCount()
|
||||
{
|
||||
MOZ_ASSERT(!GetSameTypeParentDocument());
|
||||
|
||||
++mNumTrackersFound;
|
||||
if (aIsTrackerBlocked) {
|
||||
++mNumTrackersBlocked;
|
||||
}
|
||||
}
|
||||
|
||||
void IncrementTrackerBlockedCount()
|
||||
{
|
||||
MOZ_ASSERT(!GetSameTypeParentDocument());
|
||||
++mNumTrackersBlocked;
|
||||
}
|
||||
|
||||
uint32_t NumTrackersFound()
|
||||
|
|
|
@ -363,12 +363,7 @@ public class GeckoView extends FrameLayout {
|
|||
if (!mSession.isOpen()) {
|
||||
mSession.open(mRuntime);
|
||||
}
|
||||
// Temporary solution until we find out why mRuntime can end up as null here. It means we
|
||||
// might miss an orientation change if we were background OOM-killed, but it's better than
|
||||
// crashing. See bug 1484001.
|
||||
if (mRuntime != null) {
|
||||
mRuntime.orientationChanged();
|
||||
}
|
||||
mRuntime.orientationChanged();
|
||||
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
|
@ -428,11 +423,36 @@ public class GeckoView extends FrameLayout {
|
|||
final SavedState ss = (SavedState) state;
|
||||
super.onRestoreInstanceState(ss.getSuperState());
|
||||
|
||||
if (mSession == null && ss.session != null) {
|
||||
setSession(ss.session, ss.session.getRuntime());
|
||||
} else if (ss.session != null) {
|
||||
mSession.transferFrom(ss.session);
|
||||
mRuntime = mSession.getRuntime();
|
||||
restoreSession(ss.session);
|
||||
}
|
||||
|
||||
private void restoreSession(final @Nullable GeckoSession savedSession) {
|
||||
if (savedSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GeckoRuntime runtimeToRestore = savedSession.getRuntime();
|
||||
// Note: setSession sets either both mSession and mRuntime, or none of them. So if we don't
|
||||
// have an mRuntime here, we won't have an mSession, either.
|
||||
if (mRuntime == null) {
|
||||
if (runtimeToRestore == null) {
|
||||
// If the saved session is closed, we fall back to using the default runtime, same
|
||||
// as we do when we don't even have an mSession in onAttachedToWindow().
|
||||
runtimeToRestore = GeckoRuntime.getDefault(getContext());
|
||||
}
|
||||
setSession(savedSession, runtimeToRestore);
|
||||
// We already have a session. We only want to transfer the saved session if its close/open
|
||||
// state is the same or better as our current session.
|
||||
} else if (savedSession.isOpen() || !mSession.isOpen()) {
|
||||
if (mSession.isOpen()) {
|
||||
mSession.close();
|
||||
}
|
||||
mSession.transferFrom(savedSession);
|
||||
if (runtimeToRestore != null) {
|
||||
// If the saved session was open, we transfer its runtime as well. Otherwise we just
|
||||
// keep the runtime we already had in mRuntime.
|
||||
mRuntime = runtimeToRestore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -911,8 +911,6 @@ nsChannelClassifier::SetBlockedContent(nsIChannel *channel,
|
|||
nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
|
||||
NS_ENSURE_TRUE(doc, NS_OK);
|
||||
|
||||
doc->IncrementTrackerCount(true);
|
||||
|
||||
unsigned state;
|
||||
if (aErrorCode == NS_ERROR_TRACKING_URI) {
|
||||
state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
|
||||
|
|
|
@ -331,6 +331,10 @@ HttpBaseChannel::SetIsTrackingResource(bool aIsThirdParty)
|
|||
MOZ_ASSERT(!mIsThirdPartyTrackingResource);
|
||||
mIsFirstPartyTrackingResource = true;
|
||||
}
|
||||
|
||||
if (mLoadInfo) {
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -747,10 +747,10 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
}
|
||||
|
||||
bool isTracker;
|
||||
if (NS_SUCCEEDED(mLoadInfo->GetIsTracker(&isTracker)) && isTracker) {
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetIsTracker(&isTracker));
|
||||
if (isTracker) {
|
||||
bool isTrackerBlocked;
|
||||
Unused << mLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked);
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked));
|
||||
LOG(("HttpChannelChild::DoOnStartRequest FastBlock %d [this=%p]\n",
|
||||
isTrackerBlocked,
|
||||
this));
|
||||
|
@ -758,8 +758,10 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
nsCOMPtr<nsIDocument> doc;
|
||||
if (!NS_WARN_IF(NS_FAILED(GetTopDocument(this,
|
||||
getter_AddRefs(doc))))) {
|
||||
|
||||
doc->IncrementTrackerCount(isTrackerBlocked);
|
||||
doc->IncrementTrackerCount();
|
||||
if (isTrackerBlocked) {
|
||||
doc->IncrementTrackerBlockedCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -694,6 +694,7 @@ bool
|
|||
nsHttpChannel::CheckFastBlocked()
|
||||
{
|
||||
LOG(("nsHttpChannel::CheckFastBlocked [this=%p]\n", this));
|
||||
MOZ_ASSERT(mIsThirdPartyTrackingResource);
|
||||
|
||||
static bool sFastBlockInited = false;
|
||||
static bool sIsFastBlockEnabled = false;
|
||||
|
@ -706,25 +707,28 @@ nsHttpChannel::CheckFastBlocked()
|
|||
}
|
||||
|
||||
TimeStamp timestamp;
|
||||
if (NS_FAILED(GetNavigationStartTimeStamp(×tamp))) {
|
||||
if (NS_FAILED(GetNavigationStartTimeStamp(×tamp)) || !timestamp) {
|
||||
LOG(("FastBlock passed (no timestamp) [this=%p]\n", this));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StaticPrefs::browser_contentblocking_enabled() ||
|
||||
!sIsFastBlockEnabled ||
|
||||
IsContentPolicyTypeWhitelistedForFastBlock(mLoadInfo) ||
|
||||
!timestamp ||
|
||||
// If the user has interacted with the document, we disable fastblock.
|
||||
(mLoadInfo && mLoadInfo->GetDocumentHasUserInteracted())) {
|
||||
|
||||
LOG(("FastBlock passed (invalid) [this=%p]\n", this));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TimeDuration duration = TimeStamp::NowLoRes() - timestamp;
|
||||
bool isFastBlocking = duration.ToMilliseconds() >= sFastBlockTimeout;
|
||||
|
||||
if (mLoadInfo) {
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(isFastBlocking));
|
||||
if (isFastBlocking && mLoadInfo) {
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
|
||||
}
|
||||
|
||||
LOG(("FastBlock %s (%lf) [this=%p]\n",
|
||||
|
@ -6109,6 +6113,10 @@ nsHttpChannel::CancelInternal(nsresult status)
|
|||
!!mTrackingProtectionCancellationPending;
|
||||
if (status == NS_ERROR_TRACKING_URI) {
|
||||
mTrackingProtectionCancellationPending = 0;
|
||||
if (mLoadInfo) {
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
|
||||
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(true));
|
||||
}
|
||||
}
|
||||
|
||||
mCanceled = true;
|
||||
|
|
|
@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
|
|||
|
||||
The bits labelled 'x', 'p', and 'g' are feature flags.
|
||||
|
||||
The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
|
||||
and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
|
||||
The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
|
||||
and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
|
||||
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
|
||||
ARM64 is also known as AArch64; it is logically ARMv8.)
|
||||
|
||||
For the same release, x86 and ARM64 builds have higher version codes and
|
||||
For the same release, x86 and x86_64 builds have higher version codes and
|
||||
take precedence over ARM builds, so that they are preferred over ARM on
|
||||
devices that have ARM emulation.
|
||||
|
||||
The bit labelled 'p' is a placeholder that is always 0 (for now).
|
||||
The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
|
||||
or ARM64), and 0 otherwise, which means the build is for a 32-bit
|
||||
architecture (x86 or ARM). 64-bit builds have higher version codes so
|
||||
they take precedence over 32-bit builds on devices that support 64-bit.
|
||||
|
||||
Firefox no longer supports API 14 or earlier.
|
||||
|
||||
This version code computation allows for a split on API levels that allowed
|
||||
us to ship builds specifically for Gingerbread (API 9-10); we preserve
|
||||
that functionality for sanity's sake, and to allow us to reintroduce a
|
||||
split in the future.
|
||||
|
||||
At present, the bit labelled 'g' is 1 if the build is an ARM build
|
||||
targeting API 16+, which will always be the case.
|
||||
The bit labelled 'g' is 1 if the build targets a recent API level, which
|
||||
is currently always the case, because Firefox no longer ships releases that
|
||||
are split by API levels. However, we may reintroduce a split in the future,
|
||||
in which case the release that targets an older API level will
|
||||
|
||||
We throw an explanatory exception when we are within one calendar year of
|
||||
running out of build events. This gives lots of time to update the version
|
||||
|
@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
|
|||
# for architecture and APK splits.
|
||||
version |= base << 3
|
||||
|
||||
# None is interpreted as arm.
|
||||
if not cpu_arch or cpu_arch == 'armeabi-v7a':
|
||||
# 0 is interpreted as SDK 9.
|
||||
if not min_sdk or min_sdk == 9:
|
||||
pass
|
||||
# This used to compare to 11. The 16+ APK directly supersedes 11+, so
|
||||
# we reuse this check.
|
||||
elif min_sdk == 16:
|
||||
version |= 1 << 0
|
||||
else:
|
||||
raise ValueError("Don't know how to compute android:versionCode "
|
||||
"for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
|
||||
elif cpu_arch in ['x86', 'arm64-v8a']:
|
||||
# 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
|
||||
if cpu_arch in ['x86', 'x86_64']:
|
||||
version |= 1 << 2
|
||||
elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
|
||||
pass
|
||||
else:
|
||||
raise ValueError("Don't know how to compute android:versionCode "
|
||||
"for CPU arch %s" % cpu_arch)
|
||||
|
||||
# 'p' bit is 1 for 64-bit architectures.
|
||||
if cpu_arch in ['arm64-v8a', 'x86_64']:
|
||||
version |= 1 << 1
|
||||
elif cpu_arch in ['armeabi-v7a', 'x86']:
|
||||
pass
|
||||
else:
|
||||
raise ValueError("Don't know how to compute android:versionCode "
|
||||
"for CPU arch %s" % cpu_arch)
|
||||
|
||||
# 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
|
||||
version |= 1 << 0
|
||||
|
||||
return version
|
||||
|
||||
def android_version_code(buildid, *args, **kwargs):
|
||||
|
|
|
@ -178,8 +178,7 @@ class LintRoller(object):
|
|||
:param outgoing: Lint files touched by commits that are not on the remote repository.
|
||||
:param workdir: Lint all files touched in the working directory.
|
||||
:param num_procs: The number of processes to use. Default: cpu count
|
||||
:return: A dictionary with file names as the key, and a list of
|
||||
:class:`~result.Issue`s as the value.
|
||||
:return: A :class:`~result.ResultSummary` instance.
|
||||
"""
|
||||
if not self.linters:
|
||||
raise LintersNotConfigured
|
||||
|
@ -215,7 +214,7 @@ class LintRoller(object):
|
|||
|
||||
if not (paths or vcs_paths) and (workdir or outgoing):
|
||||
print("warning: no files linted")
|
||||
return {}
|
||||
return self.result
|
||||
|
||||
# Make sure all paths are absolute. Join `paths` to cwd and `vcs_paths` to root.
|
||||
paths = set(map(os.path.abspath, paths))
|
||||
|
|
|
@ -100,6 +100,18 @@ def test_roll_with_excluded_path(lint, linters, files):
|
|||
assert result.failed == set([])
|
||||
|
||||
|
||||
def test_roll_with_no_files_to_lint(lint, linters, capfd):
|
||||
lint.read(linters)
|
||||
lint.mock_vcs([])
|
||||
result = lint.roll([], workdir=True)
|
||||
assert isinstance(result, ResultSummary)
|
||||
assert len(result.issues) == 0
|
||||
assert len(result.failed) == 0
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
assert 'warning: no files linted' in out
|
||||
|
||||
|
||||
def test_roll_with_invalid_extension(lint, lintdir, filedir):
|
||||
lint.read(os.path.join(lintdir, 'external.yml'))
|
||||
result = lint.roll(os.path.join(filedir, 'foobar.py'))
|
||||
|
|
|
@ -14,39 +14,7 @@ cd $HOME_DIR/src
|
|||
git clone -n https://github.com/llvm-mirror/llvm
|
||||
|
||||
cd llvm
|
||||
git checkout 4727bc748a48e46824eae55a81ae890cd25c3a34
|
||||
|
||||
patch -p1 <<'EOF'
|
||||
diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
|
||||
index 17559d2..b08a8d9 100644
|
||||
--- a/lib/DebugInfo/DWARF/DWARFDie.cpp
|
||||
+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
|
||||
@@ -304,20 +304,24 @@ DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
|
||||
|
||||
Optional<DWARFFormValue>
|
||||
DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
|
||||
if (!isValid())
|
||||
return None;
|
||||
if (auto Value = find(Attrs))
|
||||
return Value;
|
||||
if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) {
|
||||
+ if (Die.getOffset() == getOffset())
|
||||
+ return None;
|
||||
if (auto Value = Die.findRecursively(Attrs))
|
||||
return Value;
|
||||
}
|
||||
if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification)) {
|
||||
+ if (Die.getOffset() == getOffset())
|
||||
+ return None;
|
||||
if (auto Value = Die.findRecursively(Attrs))
|
||||
return Value;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
DWARFDie
|
||||
DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
|
||||
EOF
|
||||
git checkout 9df0977d9409b093156ebbd8e1ac99bc32b9eb39
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
@ -60,9 +28,9 @@ cmake \
|
|||
|
||||
export LD_LIBRARY_PATH=$HOME_DIR/src/gcc/lib64
|
||||
|
||||
ninja llvm-dsymutil llvm-symbolizer
|
||||
ninja dsymutil llvm-symbolizer
|
||||
|
||||
tar --xform='s,^,llvm-dsymutil/,' -Jcf llvm-dsymutil.tar.xz bin/llvm-dsymutil bin/llvm-symbolizer
|
||||
tar --xform='s,^,llvm-dsymutil/,' -Jcf llvm-dsymutil.tar.xz bin/dsymutil bin/llvm-symbolizer
|
||||
|
||||
mkdir -p $UPLOAD_DIR
|
||||
cp llvm-dsymutil.tar.xz $UPLOAD_DIR
|
||||
|
|
|
@ -3143,7 +3143,7 @@ GeckoDriver.prototype.dismissDialog = async function() {
|
|||
|
||||
await new Promise(resolve => {
|
||||
win.addEventListener("DOMModalDialogClosed", whenIdle(win, () => {
|
||||
this.dialog = modal.findModalDialogs(this.curBrowser);
|
||||
this.dialog = null;
|
||||
resolve();
|
||||
}), {once: true});
|
||||
|
||||
|
@ -3162,7 +3162,7 @@ GeckoDriver.prototype.acceptDialog = async function() {
|
|||
|
||||
await new Promise(resolve => {
|
||||
win.addEventListener("DOMModalDialogClosed", whenIdle(win, () => {
|
||||
this.dialog = modal.findModalDialogs(this.curBrowser);
|
||||
this.dialog = null;
|
||||
resolve();
|
||||
}), {once: true});
|
||||
|
||||
|
|
|
@ -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/.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from marionette_driver.by import By
|
||||
|
@ -6,7 +10,7 @@ from marionette_driver import errors
|
|||
from marionette_driver.marionette import Alert
|
||||
from marionette_driver.wait import Wait
|
||||
|
||||
from marionette_harness import MarionetteTestCase, parameterized, WindowManagerMixin
|
||||
from marionette_harness import MarionetteTestCase, WindowManagerMixin
|
||||
|
||||
|
||||
class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
|
||||
|
@ -23,6 +27,10 @@ class BaseAlertTestCase(WindowManagerMixin, MarionetteTestCase):
|
|||
Wait(self.marionette, timeout=timeout).until(
|
||||
lambda _: self.alert_present)
|
||||
|
||||
def wait_for_alert_closed(self, timeout=None):
|
||||
Wait(self.marionette, timeout=timeout).until(
|
||||
lambda _: not self.alert_present)
|
||||
|
||||
|
||||
class TestTabModalAlerts(BaseAlertTestCase):
|
||||
|
||||
|
@ -35,12 +43,13 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
self.marionette.navigate(self.test_page)
|
||||
|
||||
def tearDown(self):
|
||||
# Ensure to close all possible remaining tab modal dialogs
|
||||
# Ensure to close a possible remaining tab modal dialog
|
||||
try:
|
||||
while True:
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
except errors.NoAlertPresentException:
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
self.wait_for_alert_closed()
|
||||
except:
|
||||
pass
|
||||
|
||||
super(TestTabModalAlerts, self).tearDown()
|
||||
|
@ -51,6 +60,50 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
with self.assertRaises(errors.NoAlertPresentException):
|
||||
Alert(self.marionette).dismiss()
|
||||
|
||||
def test_alert_accept(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.accept()
|
||||
|
||||
def test_alert_dismiss(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
def test_confirm_accept(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-confirm").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.accept()
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "confirm-result").text == "true")
|
||||
|
||||
def test_confirm_dismiss(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-confirm").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "confirm-result").text == "false")
|
||||
|
||||
def test_prompt_accept(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.accept()
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "prompt-result").text == "")
|
||||
|
||||
def test_prompt_dismiss(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
|
||||
|
||||
def test_alert_opened_before_session_starts(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
|
@ -62,45 +115,40 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
@parameterized("alert", "alert", "undefined")
|
||||
@parameterized("confirm", "confirm", "true")
|
||||
@parameterized("prompt", "prompt", "")
|
||||
def test_accept(self, value, result):
|
||||
self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.accept()
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
|
||||
|
||||
@parameterized("alert", "alert", "undefined")
|
||||
@parameterized("confirm", "confirm", "false")
|
||||
@parameterized("prompt", "prompt", "null")
|
||||
def test_dismiss(self, value, result):
|
||||
self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text").text, result)
|
||||
|
||||
@parameterized("alert", "alert", "Marionette alert")
|
||||
@parameterized("confirm", "confirm", "Marionette confirm")
|
||||
@parameterized("prompt", "prompt", "Marionette prompt")
|
||||
def test_text(self, value, text):
|
||||
def test_alert_text(self):
|
||||
with self.assertRaises(errors.NoAlertPresentException):
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.text
|
||||
self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
self.assertEqual(alert.text, text)
|
||||
self.assertEqual(alert.text, "Marionette alert")
|
||||
alert.accept()
|
||||
|
||||
@parameterized("alert", "alert")
|
||||
@parameterized("confirm", "confirm")
|
||||
def test_set_text_throws(self, value):
|
||||
def test_prompt_text(self):
|
||||
with self.assertRaises(errors.NoAlertPresentException):
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.text
|
||||
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
self.assertEqual(alert.text, "Marionette prompt")
|
||||
alert.accept()
|
||||
|
||||
def test_confirm_text(self):
|
||||
with self.assertRaises(errors.NoAlertPresentException):
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.text
|
||||
self.marionette.find_element(By.ID, "tab-modal-confirm").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
self.assertEqual(alert.text, "Marionette confirm")
|
||||
alert.accept()
|
||||
|
||||
def test_set_text_throws(self):
|
||||
with self.assertRaises(errors.NoAlertPresentException):
|
||||
Alert(self.marionette).send_keys("Foo")
|
||||
self.marionette.find_element(By.ID, "tab-modal-{}".format(value)).click()
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
with self.assertRaises(errors.ElementNotInteractableException):
|
||||
|
@ -111,9 +159,10 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
|
||||
self.wait_for_alert()
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.send_keys("Foo bar")
|
||||
alert.send_keys("Some text!")
|
||||
alert.accept()
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text").text, "Foo bar")
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "prompt-result").text == "Some text!")
|
||||
|
||||
def test_set_text_dismiss(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-prompt").click()
|
||||
|
@ -121,51 +170,35 @@ class TestTabModalAlerts(BaseAlertTestCase):
|
|||
alert = self.marionette.switch_to_alert()
|
||||
alert.send_keys("Some text!")
|
||||
alert.dismiss()
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text").text, "null")
|
||||
self.wait_for_condition(
|
||||
lambda mn: mn.find_element(By.ID, "prompt-result").text == "null")
|
||||
|
||||
def test_unrelated_command_when_alert_present(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
with self.assertRaises(errors.UnexpectedAlertOpen):
|
||||
self.marionette.find_element(By.ID, "text")
|
||||
self.marionette.find_element(By.ID, "click-result")
|
||||
|
||||
def test_modal_is_dismissed_after_unexpected_alert(self):
|
||||
self.marionette.find_element(By.ID, "tab-modal-alert").click()
|
||||
self.wait_for_alert()
|
||||
with self.assertRaises(errors.UnexpectedAlertOpen):
|
||||
self.marionette.find_element(By.ID, "text")
|
||||
self.marionette.find_element(By.ID, "click-result")
|
||||
|
||||
assert not self.alert_present
|
||||
|
||||
def test_handle_two_modal_dialogs(self):
|
||||
self.marionette.find_element(By.ID, "open-two-dialogs").click()
|
||||
|
||||
self.wait_for_alert()
|
||||
alert1 = self.marionette.switch_to_alert()
|
||||
alert1.send_keys("foo")
|
||||
alert1.accept()
|
||||
|
||||
alert2 = self.marionette.switch_to_alert()
|
||||
alert2.send_keys("bar")
|
||||
alert2.accept()
|
||||
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text1").text, "foo")
|
||||
self.assertEqual(self.marionette.find_element(By.ID, "text2").text, "bar")
|
||||
|
||||
|
||||
class TestModalAlerts(BaseAlertTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestModalAlerts, self).setUp()
|
||||
self.marionette.set_pref(
|
||||
"network.auth.non-web-content-triggered-resources-http-auth-allow",
|
||||
True)
|
||||
self.marionette.set_pref("network.auth.non-web-content-triggered-resources-http-auth-allow",
|
||||
True)
|
||||
|
||||
def tearDown(self):
|
||||
# Ensure to close a possible remaining modal dialog
|
||||
self.close_all_windows()
|
||||
self.marionette.clear_pref(
|
||||
"network.auth.non-web-content-triggered-resources-http-auth-allow")
|
||||
self.marionette.clear_pref("network.auth.non-web-content-triggered-resources-http-auth-allow")
|
||||
|
||||
super(TestModalAlerts, self).tearDown()
|
||||
|
||||
|
@ -176,6 +209,8 @@ class TestModalAlerts(BaseAlertTestCase):
|
|||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
self.wait_for_alert_closed()
|
||||
|
||||
status = Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
|
||||
element_present(By.ID, "status")
|
||||
)
|
||||
|
@ -191,3 +226,5 @@ class TestModalAlerts(BaseAlertTestCase):
|
|||
|
||||
alert = self.marionette.switch_to_alert()
|
||||
alert.dismiss()
|
||||
|
||||
self.wait_for_alert_closed()
|
||||
|
|
|
@ -7,37 +7,28 @@
|
|||
<head>
|
||||
<title>Dialog Test</title>
|
||||
<script type="text/javascript">
|
||||
function setInnerText(id, value) {
|
||||
document.getElementById(id).innerHTML = "<p>" + value + "</p>";
|
||||
}
|
||||
|
||||
function handleAlert () {
|
||||
setInnerText("text", alert("Marionette alert"));
|
||||
window.alert('Marionette alert');
|
||||
}
|
||||
|
||||
function handleConfirm () {
|
||||
setInnerText("text", confirm("Marionette confirm"));
|
||||
var alertAccepted = window.confirm('Marionette confirm');
|
||||
document.getElementById('confirm-result').innerHTML = alertAccepted;
|
||||
}
|
||||
|
||||
function handlePrompt () {
|
||||
setInnerText("text", prompt("Marionette prompt"));
|
||||
}
|
||||
|
||||
function handleTwoDialogs() {
|
||||
setInnerText("text1", prompt("First"));
|
||||
setInnerText("text2", prompt("Second"));
|
||||
var promptText = window.prompt('Marionette prompt');
|
||||
document.getElementById('prompt-result').innerHTML = promptText === null ? 'null' : promptText;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="#" id="tab-modal-alert" onclick="handleAlert()">Open an alert dialog.</a>
|
||||
<a href="#" id="tab-modal-confirm" onclick="handleConfirm()">Open a confirm dialog.</a>
|
||||
<a href="#" id="tab-modal-prompt" onclick="handlePrompt()">Open a prompt dialog.</a>
|
||||
<a href="#" id="open-two-dialogs" onclick="handleTwoDialogs()">Open two prompts.</a>
|
||||
<a href="#" id="click-handler" onclick="document.getElementById('text').innerHTML='result';">Make text appear.</a>
|
||||
|
||||
<div id="text"></div>
|
||||
<div id="text1"></div>
|
||||
<div id="text2"></div>
|
||||
<a href="#" id="tab-modal-alert" onclick="handleAlert()">Open an alert dialog.</a>
|
||||
<a href="#" id="tab-modal-confirm" onclick="handleConfirm()">Open a confirm dialog.</a>
|
||||
<a href="#" id="tab-modal-prompt" onclick="handlePrompt()">Open a prompt dialog.</a>
|
||||
<a href="#" id="click-handler" onclick="document.getElementById('click-result').innerHTML='result';">Make text appear.</a>
|
||||
<div id="confirm-result"></div>
|
||||
<div id="prompt-result"></div>
|
||||
<div id="click-result"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -556,6 +556,7 @@ static const char* const kBinaryFileExtensions[] = {
|
|||
".osas", // AppleScript
|
||||
".osax", // AppleScript
|
||||
//".out", // Linux binary
|
||||
".oxt", // OpenOffice extension, can execute arbitrary code
|
||||
//".paf", // PortableApps package
|
||||
//".paq8f",
|
||||
//".paq8jd",
|
||||
|
|
|
@ -1778,6 +1778,16 @@ Engine.prototype = {
|
|||
var template = aElement.getAttribute("template");
|
||||
var resultDomain = aElement.getAttribute("resultdomain");
|
||||
|
||||
let rels = [];
|
||||
if (aElement.hasAttribute("rel")) {
|
||||
rels = aElement.getAttribute("rel").toLowerCase().split(/\s+/);
|
||||
}
|
||||
|
||||
// Support an alternate suggestion type, see bug 1425827 for details.
|
||||
if (type == "application/json" && rels.includes("suggestions")) {
|
||||
type = URLTYPE_SUGGEST_JSON;
|
||||
}
|
||||
|
||||
try {
|
||||
var url = new EngineURL(type, method, template, resultDomain);
|
||||
} catch (ex) {
|
||||
|
@ -1785,8 +1795,9 @@ Engine.prototype = {
|
|||
Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (aElement.hasAttribute("rel"))
|
||||
url.rels = aElement.getAttribute("rel").toLowerCase().split(/\s+/);
|
||||
if (rels.length) {
|
||||
url.rels = rels;
|
||||
}
|
||||
|
||||
for (var i = 0; i < aElement.children.length; ++i) {
|
||||
var param = aElement.children[i];
|
||||
|
|
|
@ -33,20 +33,24 @@ function createOpenSearchEngine(response, engineData) {
|
|||
} else {
|
||||
queryString = "?q={searchTerms}";
|
||||
}
|
||||
let type = "type='application/x-suggestions+json'";
|
||||
if (engineData.alternativeJSONType) {
|
||||
type = "type='application/json' rel='suggestions'";
|
||||
}
|
||||
|
||||
let result = "<?xml version='1.0' encoding='utf-8'?>\
|
||||
<OpenSearchDescription xmlns='http://a9.com/-/spec/opensearch/1.1/'>\
|
||||
<ShortName>" + engineData.name + "</ShortName>\
|
||||
<Description>" + engineData.description + "</Description>\
|
||||
<InputEncoding>UTF-8</InputEncoding>\
|
||||
<LongName>" + engineData.name + "</LongName>\
|
||||
<Url type='application/x-suggestions+json' method='" + engineData.method + "'\
|
||||
template='" + engineData.baseURL + "searchSuggestions.sjs" + queryString + "'>\
|
||||
" + params + "\
|
||||
</Url>\
|
||||
<Url type='text/html' method='" + engineData.method + "'\
|
||||
template='" + engineData.baseURL + queryString + "'/>\
|
||||
</OpenSearchDescription>\
|
||||
";
|
||||
let result = `<?xml version='1.0' encoding='utf-8'?>
|
||||
<OpenSearchDescription xmlns='http://a9.com/-/spec/opensearch/1.1/'>
|
||||
<ShortName>${engineData.name}</ShortName>
|
||||
<Description>${engineData.description}</Description>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<LongName>${engineData.name}</LongName>
|
||||
<Url ${type} method='${engineData.method}'
|
||||
template='${engineData.baseURL}searchSuggestions.sjs${queryString}'>
|
||||
${params}
|
||||
</Url>
|
||||
<Url type='text/html' method='${engineData.method}'
|
||||
template='${engineData.baseURL}${queryString}'/>
|
||||
</OpenSearchDescription>
|
||||
`;
|
||||
response.write(result);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ var formHistoryStartup = Cc["@mozilla.org/satchel/form-history-startup;1"].
|
|||
formHistoryStartup.observe(null, "profile-after-change", null);
|
||||
|
||||
var httpServer = new HttpServer();
|
||||
var getEngine, postEngine, unresolvableEngine;
|
||||
var getEngine, postEngine, unresolvableEngine, alternateJSONEngine;
|
||||
|
||||
function run_test() {
|
||||
Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
|
||||
|
@ -57,7 +57,14 @@ add_task(async function add_test_engines() {
|
|||
method: "GET",
|
||||
};
|
||||
|
||||
[getEngine, postEngine, unresolvableEngine] = await addTestEngines([
|
||||
let alternateJSONSuggestEngineData = {
|
||||
baseURL: gDataUrl,
|
||||
name: "Alternative JSON suggestion type",
|
||||
method: "GET",
|
||||
alternativeJSONType: true,
|
||||
};
|
||||
|
||||
[getEngine, postEngine, unresolvableEngine, alternateJSONEngine] = await addTestEngines([
|
||||
{
|
||||
name: getEngineData.name,
|
||||
xmlFileName: "engineMaker.sjs?" + JSON.stringify(getEngineData),
|
||||
|
@ -70,6 +77,10 @@ add_task(async function add_test_engines() {
|
|||
name: unresolvableEngineData.name,
|
||||
xmlFileName: "engineMaker.sjs?" + JSON.stringify(unresolvableEngineData),
|
||||
},
|
||||
{
|
||||
name: alternateJSONSuggestEngineData.name,
|
||||
xmlFileName: "engineMaker.sjs?" + JSON.stringify(alternateJSONSuggestEngineData),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -126,6 +137,17 @@ add_task(async function simple_remote_no_local_result() {
|
|||
Assert.equal(result.remote[2], "mom");
|
||||
});
|
||||
|
||||
add_task(async function simple_remote_no_local_result_alternative_type() {
|
||||
let controller = new SearchSuggestionController();
|
||||
let result = await controller.fetch("mo", false, alternateJSONEngine);
|
||||
Assert.equal(result.term, "mo");
|
||||
Assert.equal(result.local.length, 0);
|
||||
Assert.equal(result.remote.length, 3);
|
||||
Assert.equal(result.remote[0], "Mozilla");
|
||||
Assert.equal(result.remote[1], "modern");
|
||||
Assert.equal(result.remote[2], "mom");
|
||||
});
|
||||
|
||||
add_task(async function remote_term_case_mismatch() {
|
||||
let controller = new SearchSuggestionController();
|
||||
let result = await controller.fetch("Query Case Mismatch", false, getEngine);
|
||||
|
|
Загрузка…
Ссылка в новой задаче