/** * Converts a property bag to object. * @param {nsIPropertyBag} bag - The property bag to convert * @returns {Object} - The object representation of the nsIPropertyBag
*/ function propBagToObject(bag) { if (!(bag instanceof Ci.nsIPropertyBag)) { thrownew TypeError("Not a property bag");
}
let result = {}; for (let { name, value } of bag.enumerator) {
result[name] = value;
} return result;
}
var modalType; var isSelectDialog = false; var isOSX = "nsILocalFileMac" in SpecialPowers.Ci; var isE10S = SpecialPowers.Services.appinfo.processType == 2;
var gChromeScript = SpecialPowers.loadChromeScript(
SimpleTest.getTestFileURL("chromeScript.js")
);
SimpleTest.registerCleanupFunction(() => gChromeScript.destroy());
async function runPromptCombinations(window, testFunc) {
let util = new PromptTestUtil(window);
let run = () => {
info(
`Running tests (modalType=${modalType}, usePromptService=${util.usePromptService}, useBrowsingContext=${util.useBrowsingContext}, useAsync=${util.useAsync})`
); return testFunc(util);
};
// Prompt service with dom window parent only supports window prompts
util.usePromptService = true;
util.useBrowsingContext = false;
util.modalType = Ci.nsIPrompt.MODAL_TYPE_WINDOW;
modalType = util.modalType;
util.useAsync = false;
await run();
let modalTypes = [
Ci.nsIPrompt.MODAL_TYPE_WINDOW,
Ci.nsIPrompt.MODAL_TYPE_TAB,
Ci.nsIPrompt.MODAL_TYPE_CONTENT,
];
for (let type of modalTypes) {
util.modalType = type;
modalType = type;
// Prompt service with browsing context sync
util.usePromptService = true;
util.useBrowsingContext = true;
util.useAsync = false;
await run();
// Prompt service with browsing context async
util.usePromptService = true;
util.useBrowsingContext = true;
util.useAsync = true;
await run();
// nsIPrompt // modalType is set via nsIWritablePropertyBag (legacy)
util.usePromptService = false;
util.useBrowsingContext = false;
util.useAsync = false;
await run();
}
}
let interfaceName = this.usePromptService ? "Services.prompt" : "prompt";
ok( this._prompter[funcName],
`${interfaceName} should have method ${funcName}.`
);
info(`Calling ${interfaceName}.${funcName}(${args})`);
let result = this._prompter[funcName](...args);
is( this.useAsync,
result != null &&
result.constructor != null &&
result.constructor.name === "Promise", "If method is async it should return a promise."
);
if (this.useAsync) {
let propBag = await result; return propBag && propBagToObject(propBag);
} return result;
}
}
function onloadPromiseFor(id) { var iframe = document.getElementById(id); returnnew Promise(resolve => {
iframe.addEventListener( "load", function () {
resolve(true);
},
{ once: true }
);
});
}
/** * Take an action on the next prompt that appears without checking the state in advance. * This is useful when the action doesn't depend on which prompt is shown and you * are expecting multiple prompts at once in an indeterminate order. * If you know the state of the prompt you expect you should use `handlePrompt` instead. * @param {object} action defining how to handle the prompt * @returns {Promise} resolving with the prompt state.
*/ function handlePromptWithoutChecks(action) { returnnew Promise(resolve => {
gChromeScript.addMessageListener("promptHandled", function handled(msg) {
gChromeScript.removeMessageListener("promptHandled", handled);
resolve(msg.promptState);
});
gChromeScript.sendAsyncMessage("handlePrompt", { action, modalType });
});
}
async function handlePrompt(state, action) {
let actualState = await handlePromptWithoutChecks(action);
checkPromptState(actualState, state);
}
function checkPromptState(promptState, expectedState) {
info(`checkPromptState: Expected: ${expectedState.msg}`); // XXX check title? OS X has title in content
is(promptState.msg, expectedState.msg, "Checking expected message");
if (isOSX || promptState.isSubDialogPrompt || promptState.showCallerOrigin) {
ok(
!promptState.titleHidden, "Checking title always visible on OS X or when opened with common dialog"
);
} else {
is(
promptState.titleHidden,
expectedState.titleHidden, "Checking title visibility"
);
}
is(
promptState.textHidden,
expectedState.textHidden, "Checking textbox visibility"
);
is(
promptState.passHidden,
expectedState.passHidden, "Checking passbox visibility"
);
is(
promptState.checkHidden,
expectedState.checkHidden, "Checking checkbox visibility"
);
is(promptState.checkMsg, expectedState.checkMsg, "Checking checkbox label");
is(promptState.checked, expectedState.checked, "Checking checkbox checked"); if (
modalType === Ci.nsIPrompt.MODAL_TYPE_WINDOW ||
modalType === Ci.nsIPrompt.MODAL_TYPE_TAB
) {
is(
promptState.iconClass,
expectedState.iconClass, "Checking expected icon CSS class"
);
}
is(promptState.textValue, expectedState.textValue, "Checking textbox value");
is(promptState.passValue, expectedState.passValue, "Checking passbox value");
// For prompts with a time-delay button. if (expectedState.butt0Disabled) {
is(promptState.butt0Disabled, true, "Checking accept-button is disabled");
is(
promptState.butt1Disabled, false, "Checking cancel-button isn't disabled"
);
}
if (
isOSX &&
expectedState.focused &&
expectedState.focused.startsWith("button") &&
!promptState.infoRowHidden
) {
is(
promptState.focused, "infoBody", "buttons don't focus on OS X, but infoBody does instead"
);
} else {
is(promptState.focused, expectedState.focused, "Checking focused element");
}
if (expectedState.hasOwnProperty("chrome")) {
is(
promptState.chrome,
expectedState.chrome, "Dialog should be opened as chrome"
);
} if (expectedState.hasOwnProperty("dialog")) {
is(
promptState.dialog,
expectedState.dialog, "Dialog should be opened as a dialog"
);
} if (expectedState.hasOwnProperty("chromeDependent")) {
is(
promptState.chromeDependent,
expectedState.chromeDependent, "Dialog should be opened as dependent"
);
} if (expectedState.hasOwnProperty("isWindowModal")) {
is(
promptState.isWindowModal,
expectedState.isWindowModal, "Dialog should be modal"
);
}
}
function checkEchoedAuthInfo(expectedState, browsingContext) { return SpecialPowers.spawn(
browsingContext,
[expectedState.user, expectedState.pass],
(expectedUser, expectedPass) => {
let doc = this.content.document;
// The server echos back the HTTP auth info it received.
let username = doc.getElementById("user").textContent;
let password = doc.getElementById("pass").textContent;
let authok = doc.getElementById("ok").textContent;
Assert.equal(authok, "PASS", "Checking for successful authentication"); Assert.equal(username, expectedUser, "Checking for echoed username"); Assert.equal(password, expectedPass, "Checking for echoed password");
}
);
}
/** * Create a Proxy to relay method calls on an nsIAuthPrompt[2] prompter to a chrome script which can * perform the calls in the parent. Out and inout params will be copied back from the parent to * content. * * @param chromeScript The reference to the chrome script that will listen to `proxyPrompter` * messages in the parent and call the `methodName` method. * The return value from the message handler should be an object with properties: * `rv` - containing the return value of the method call. * `args` - containing the array of arguments passed to the method since out or inout ones could have * been modified.
*/ function PrompterProxy(chromeScript) { returnnew Proxy(
{},
{
get(target, prop) { return (...args) => { // Array of indices of out/inout params to copy from the parent back to the caller.
let outParams = [];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.