mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 704509 - fix reftests to work with native fennec. r=dbaron
This commit is contained in:
parent
46a35a688e
commit
8f0d429677
@ -52,6 +52,11 @@ ifdef XPI_NAME
|
||||
NO_JS_MANIFEST = 1
|
||||
DIST_FILES = install.rdf
|
||||
|
||||
ifeq ($(MOZ_BUILD_APP),mobile/android)
|
||||
DEFINES += -DBOOTSTRAP
|
||||
DIST_FILES += bootstrap.js
|
||||
endif
|
||||
|
||||
# Used in install.rdf
|
||||
USE_EXTENSION_MANIFEST=1
|
||||
else
|
||||
|
80
layout/tools/reftest/bootstrap.js
vendored
Normal file
80
layout/tools/reftest/bootstrap.js
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
function loadIntoWindow(window) {}
|
||||
function unloadFromWindow(window) {}
|
||||
|
||||
function setDefaultPrefs() {
|
||||
// This code sets the preferences for extension-based reftest; for
|
||||
// command-line based reftest they are set in function handler_handle in
|
||||
// reftest-cmdline.js. These two locations should stay in sync.
|
||||
//
|
||||
// FIXME: These should be in only one place.
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefService);
|
||||
var branch = prefs.getDefaultBranch("");
|
||||
branch.setBoolPref("gfx.color_management.force_srgb", true);
|
||||
branch.setBoolPref("browser.dom.window.dump.enabled", true);
|
||||
branch.setIntPref("ui.caretBlinkTime", -1);
|
||||
branch.setBoolPref("dom.send_after_paint_to_content", true);
|
||||
// no slow script dialogs
|
||||
branch.setIntPref("dom.max_script_run_time", 0);
|
||||
branch.setIntPref("dom.max_chrome_script_run_time", 0);
|
||||
branch.setIntPref("hangmonitor.timeout", 0);
|
||||
}
|
||||
|
||||
var windowListener = {
|
||||
onOpenWindow: function(aWindow) {
|
||||
let domWindow = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal || Components.interfaces.nsIDOMWindow);
|
||||
domWindow.addEventListener("load", function() {
|
||||
domWindow.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
|
||||
|
||||
// Load into any existing windows
|
||||
let enumerator = wm.getEnumerator("navigator:browser");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext().QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
setDefaultPrefs();
|
||||
Components.utils.import("chrome://reftest/content/reftest.jsm");
|
||||
win.addEventListener("UIReady", function() {OnRefTestLoad(win);});
|
||||
break;
|
||||
}
|
||||
|
||||
}, false);
|
||||
},
|
||||
onCloseWindow: function(aWindow){ },
|
||||
onWindowTitleChange: function(){ },
|
||||
};
|
||||
|
||||
function startup(aData, aReason) {
|
||||
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService (Components.interfaces.nsIWindowMediator);
|
||||
|
||||
Components.manager.addBootstrappedManifestLocation(aData.installPath);
|
||||
|
||||
// Load into any new windows
|
||||
wm.addListener(windowListener);
|
||||
}
|
||||
|
||||
function shutdown(aData, aReason) {
|
||||
// When the application is shutting down we normally don't have to clean up any UI changes
|
||||
if (aReason == APP_SHUTDOWN)
|
||||
return;
|
||||
|
||||
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Components.interfaces.nsIWindowMediator);
|
||||
|
||||
// Stop watching for new windows
|
||||
wm.removeListener(windowListener);
|
||||
|
||||
// Unload from any existing windows
|
||||
let enumerator = wm.getEnumerator("navigator:browser");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext().QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
unloadFromWindow(win);
|
||||
}
|
||||
}
|
||||
|
||||
function install(aData, aReason) { }
|
||||
function uninstall(aData, aReason) { }
|
||||
|
@ -4,6 +4,10 @@
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>reftest@mozilla.org</em:id>
|
||||
#ifdef BOOTSTRAP
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
#endif
|
||||
<em:version>1.0</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
|
@ -1,10 +1,14 @@
|
||||
reftest.jar:
|
||||
% content reftest %content/
|
||||
* content/reftest.js (reftest.js)
|
||||
content/reftest-content.js (reftest-content.js)
|
||||
#ifdef BOOTSTRAP
|
||||
* content/reftest.jsm (reftest.js)
|
||||
#else
|
||||
* content/reftest.js (reftest.js)
|
||||
content/reftest.xul (reftest.xul)
|
||||
#ifdef XPI_NAME
|
||||
% component {32530271-8c1b-4b7d-a812-218e42c6bb23} components/reftest-cmdline.js
|
||||
% contract @mozilla.org/commandlinehandler/general-startup;1?type=reftest {32530271-8c1b-4b7d-a812-218e42c6bb23}
|
||||
% category command-line-handler m-reftest @mozilla.org/commandlinehandler/general-startup;1?type=reftest
|
||||
#endif
|
||||
#endif
|
||||
|
@ -100,6 +100,12 @@ RefTestCmdLineHandler.prototype =
|
||||
* We want to do this here rather than in reftest.js because it's
|
||||
* important to force sRGB as an output profile for color management
|
||||
* before we load a window.
|
||||
*
|
||||
* If you change these, please adjust them in the bootstrap.js function
|
||||
* setDefaultPrefs(). These are duplicated there so we can have a
|
||||
* restartless addon for reftest on native Android.
|
||||
*
|
||||
* FIXME: These should be in only one place.
|
||||
*/
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefService);
|
||||
|
@ -36,6 +36,11 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#if BOOTSTRAP
|
||||
var EXPORTED_SYMBOLS = ["OnRefTestLoad"];
|
||||
#endif
|
||||
|
||||
|
||||
const CC = Components.classes;
|
||||
const CI = Components.interfaces;
|
||||
const CR = Components.results;
|
||||
@ -219,7 +224,7 @@ function IDForEventTarget(event)
|
||||
}
|
||||
}
|
||||
|
||||
function OnRefTestLoad()
|
||||
function OnRefTestLoad(win)
|
||||
{
|
||||
gCrashDumpDir = CC[NS_DIRECTORY_SERVICE_CONTRACTID]
|
||||
.getService(CI.nsIProperties)
|
||||
@ -238,8 +243,11 @@ function OnRefTestLoad()
|
||||
gBrowserIsRemote = false;
|
||||
}
|
||||
|
||||
if (gContainingWindow == null && window != null) {
|
||||
gContainingWindow = window;
|
||||
if (win === undefined || win == null) {
|
||||
win = window;
|
||||
}
|
||||
if (gContainingWindow == null && win != null) {
|
||||
gContainingWindow = win;
|
||||
}
|
||||
|
||||
gBrowser = gContainingWindow.document.createElementNS(XUL_NS, "xul:browser");
|
||||
@ -250,7 +258,15 @@ function OnRefTestLoad()
|
||||
// what size our window is
|
||||
gBrowser.setAttribute("style", "min-width: 800px; min-height: 1000px; max-width: 800px; max-height: 1000px");
|
||||
|
||||
#if BOOTSTRAP
|
||||
var doc = gContainingWindow.document.getElementById('main-window');
|
||||
while (doc.hasChildNodes()) {
|
||||
doc.removeChild(doc.firstChild);
|
||||
}
|
||||
doc.appendChild(gBrowser);
|
||||
#else
|
||||
document.getElementById("reftest-window").appendChild(gBrowser);
|
||||
#endif
|
||||
|
||||
gBrowserMessageManager = gBrowser.QueryInterface(CI.nsIFrameLoaderOwner)
|
||||
.frameLoader.messageManager;
|
||||
@ -285,7 +301,11 @@ function InitAndStartRefTests()
|
||||
var mfl = FileUtils.openFileOutputStream(f, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
|
||||
// Set to mirror to stdout as well as the file
|
||||
gDumpLog = function (msg) {
|
||||
#if BOOTSTRAP
|
||||
//NOTE: on android-xul, we have a libc crash if we do a dump with %7s in the string
|
||||
#else
|
||||
dump(msg);
|
||||
#endif
|
||||
mfl.write(msg, msg.length);
|
||||
};
|
||||
}
|
||||
@ -373,6 +393,38 @@ function StartHTTPServer()
|
||||
|
||||
function StartTests()
|
||||
{
|
||||
#if BOOTSTRAP
|
||||
/* These prefs are optional, so we don't need to spit an error to the log */
|
||||
try {
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
} catch(e) {
|
||||
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + e + "\n");
|
||||
}
|
||||
|
||||
try {
|
||||
gNoCanvasCache = prefs.getIntPref("reftest.nocache");
|
||||
} catch(e) {
|
||||
gNoCanvasCache = false;
|
||||
}
|
||||
|
||||
try {
|
||||
gRunSlowTests = prefs.getIntPref("reftest.skipslowtests");
|
||||
} catch(e) {
|
||||
gRunSlowTests = false;
|
||||
}
|
||||
|
||||
try {
|
||||
uri = prefs.getCharPref("reftest.uri");
|
||||
} catch(e) {
|
||||
uri = "";
|
||||
}
|
||||
|
||||
if (uri == "") {
|
||||
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | Unable to find reftest.uri pref. Please ensure your profile is setup properly\n");
|
||||
DoneTests();
|
||||
}
|
||||
#else
|
||||
try {
|
||||
// Need to read the manifest once we have the final HTTP_SERVER_PORT.
|
||||
var args = window.arguments[0].wrappedJSObject;
|
||||
@ -383,16 +435,25 @@ function StartTests()
|
||||
if ("skipslowtests" in args && args.skipslowtests)
|
||||
gRunSlowTests = false;
|
||||
|
||||
ReadTopManifest(args.uri);
|
||||
uri = args.uri;
|
||||
} catch (e) {
|
||||
++gTestResults.Exception;
|
||||
gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | EXCEPTION: " + ex + "\n");
|
||||
DoneTests();
|
||||
}
|
||||
#endif
|
||||
|
||||
try {
|
||||
ReadTopManifest(uri);
|
||||
BuildUseCounts();
|
||||
|
||||
if (gTotalChunks > 0 && gThisChunk > 0) {
|
||||
var testsPerChunk = gURLs.length / gTotalChunks;
|
||||
var start = Math.round((gThisChunk-1) * testsPerChunk);
|
||||
var end = Math.round(gThisChunk * testsPerChunk);
|
||||
gURLs = gURLs.slice(start, end);
|
||||
gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. ")
|
||||
gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n");
|
||||
var testsPerChunk = gURLs.length / gTotalChunks;
|
||||
var start = Math.round((gThisChunk-1) * testsPerChunk);
|
||||
var end = Math.round(gThisChunk * testsPerChunk);
|
||||
gURLs = gURLs.slice(start, end);
|
||||
gDumpLog("REFTEST INFO | Running chunk " + gThisChunk + " out of " + gTotalChunks + " chunks. ")
|
||||
gDumpLog("tests " + (start+1) + "-" + end + "/" + gURLs.length + "\n");
|
||||
}
|
||||
gTotalTests = gURLs.length;
|
||||
|
||||
@ -417,17 +478,17 @@ function OnRefTestUnload()
|
||||
// as a string.
|
||||
function getStreamContent(inputStream)
|
||||
{
|
||||
var streamBuf = "";
|
||||
var sis = CC["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(CI.nsIScriptableInputStream);
|
||||
sis.init(inputStream);
|
||||
var streamBuf = "";
|
||||
var sis = CC["@mozilla.org/scriptableinputstream;1"].
|
||||
createInstance(CI.nsIScriptableInputStream);
|
||||
sis.init(inputStream);
|
||||
|
||||
var available;
|
||||
while ((available = sis.available()) != 0) {
|
||||
streamBuf += sis.read(available);
|
||||
}
|
||||
|
||||
return streamBuf;
|
||||
var available;
|
||||
while ((available = sis.available()) != 0) {
|
||||
streamBuf += sis.read(available);
|
||||
}
|
||||
|
||||
return streamBuf;
|
||||
}
|
||||
|
||||
// Build the sandbox for fails-if(), etc., condition evaluation.
|
||||
@ -440,16 +501,16 @@ function BuildConditionSandbox(aURL) {
|
||||
// xr.XPCOMABI throws exception for configurations without full ABI
|
||||
// support (mobile builds on ARM)
|
||||
try {
|
||||
sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI;
|
||||
sandbox.xulRuntime.XPCOMABI = xr.XPCOMABI;
|
||||
} catch(e) {
|
||||
sandbox.xulRuntime.XPCOMABI = "";
|
||||
sandbox.xulRuntime.XPCOMABI = "";
|
||||
}
|
||||
|
||||
try {
|
||||
// nsIGfxInfo is currently only implemented on Windows
|
||||
sandbox.d2d = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled;
|
||||
// nsIGfxInfo is currently only implemented on Windows
|
||||
sandbox.d2d = (NS_GFXINFO_CONTRACTID in CC) && CC[NS_GFXINFO_CONTRACTID].getService(CI.nsIGfxInfo).D2DEnabled;
|
||||
} catch(e) {
|
||||
sandbox.d2d = false;
|
||||
sandbox.d2d = false;
|
||||
}
|
||||
|
||||
sandbox.layersGPUAccelerated =
|
||||
@ -515,7 +576,7 @@ function BuildConditionSandbox(aURL) {
|
||||
|
||||
sandbox.testPluginIsOOP = function () {
|
||||
try {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
} catch (ex) {}
|
||||
|
||||
var prefservice = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
@ -566,7 +627,7 @@ function ReadTopManifest(aFileURL)
|
||||
gURLs = new Array();
|
||||
var url = gIOService.newURI(aFileURL, null, null);
|
||||
if (!url)
|
||||
throw "Expected a file or http URL for the manifest.";
|
||||
throw "Expected a file or http URL for the manifest.";
|
||||
ReadManifest(url, EXPECTED_PASS);
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,10 @@ class RemoteOptions(ReftestOptions):
|
||||
help = "name of the pidfile to generate")
|
||||
defaults["pidFile"] = ""
|
||||
|
||||
self.add_option("--bootstrap", action="store_true", dest = "bootstrap",
|
||||
help = "test with a bootstrap addon required for native Fennec")
|
||||
defaults["bootstrap"] = False
|
||||
|
||||
self.add_option("--dm_trans", action="store",
|
||||
type = "string", dest = "dm_trans",
|
||||
help = "the transport to use to communicate with device: [adb|sut]; default=sut")
|
||||
@ -290,13 +294,13 @@ class RemoteReftest(RefTest):
|
||||
localAutomation.UNIXISH = False
|
||||
hostos = sys.platform
|
||||
if (hostos == 'mac' or hostos == 'darwin'):
|
||||
localAutomation.IS_MAC = True
|
||||
localAutomation.IS_MAC = True
|
||||
elif (hostos == 'linux' or hostos == 'linux2'):
|
||||
localAutomation.IS_LINUX = True
|
||||
localAutomation.UNIXISH = True
|
||||
localAutomation.IS_LINUX = True
|
||||
localAutomation.UNIXISH = True
|
||||
elif (hostos == 'win32' or hostos == 'win64'):
|
||||
localAutomation.BIN_SUFFIX = ".exe"
|
||||
localAutomation.IS_WIN32 = True
|
||||
localAutomation.BIN_SUFFIX = ".exe"
|
||||
localAutomation.IS_WIN32 = True
|
||||
|
||||
paths = [options.xrePath, localAutomation.DIST_BIN, self.automation._product, os.path.join('..', self.automation._product)]
|
||||
options.xrePath = self.findPath(paths)
|
||||
@ -328,8 +332,8 @@ class RemoteReftest(RefTest):
|
||||
def stopWebServer(self, options):
|
||||
self.server.stop()
|
||||
|
||||
def createReftestProfile(self, options, profileDir):
|
||||
RefTest.createReftestProfile(self, options, profileDir, server=options.remoteWebServer)
|
||||
def createReftestProfile(self, options, profileDir, reftestlist):
|
||||
RefTest.createReftestProfile(self, options, profileDir, reftestlist, server=options.remoteWebServer)
|
||||
|
||||
# Turn off the locale picker screen
|
||||
fhandle = open(os.path.join(profileDir, "user.js"), 'a')
|
||||
@ -337,11 +341,14 @@ class RemoteReftest(RefTest):
|
||||
user_pref("browser.firstrun.show.localepicker", false);
|
||||
user_pref("font.size.inflation.emPerLine", 0);
|
||||
user_pref("font.size.inflation.minTwips", 0);
|
||||
""")
|
||||
user_pref("reftest.remote", true);
|
||||
user_pref("toolkit.telemetry.prompted", true);
|
||||
user_pref("reftest.uri", "%s");
|
||||
""" % reftestlist)
|
||||
|
||||
#workaround for jsreftests.
|
||||
if options.enablePrivilege:
|
||||
fhandle.write("""
|
||||
fhandle.write("""
|
||||
user_pref("capability.principal.codebase.p2.granted", "UniversalPreferencesWrite UniversalXPConnect UniversalBrowserWrite UniversalPreferencesRead UniversalBrowserRead");
|
||||
user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
|
||||
""" % (options.remoteWebServer, options.httpPort))
|
||||
@ -349,7 +356,6 @@ user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
|
||||
# Close the file
|
||||
fhandle.close()
|
||||
|
||||
|
||||
if (self._devicemanager.pushDir(profileDir, options.remoteProfile) == None):
|
||||
raise devicemanager.FileError("Failed to copy profiledir to device")
|
||||
|
||||
@ -359,6 +365,9 @@ user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
|
||||
raise devicemanager.FileError("Failed to copy extra files to device")
|
||||
|
||||
def registerExtension(self, browserEnv, options, profileDir, extraArgs = ['-silent'] ):
|
||||
if options.bootstrap:
|
||||
return
|
||||
|
||||
self.automation.log.info("REFTEST INFO | runreftest.py | Performing extension manager registration: start.\n")
|
||||
# Because our startProcess code doesn't return until fennec starts we just give it
|
||||
# a maxTime of 20 secs before timing it out and ensuring it is dead.
|
||||
@ -449,18 +458,22 @@ def main():
|
||||
|
||||
procName = options.app.split('/')[-1]
|
||||
if (dm.processExist(procName)):
|
||||
dm.killProcess(procName)
|
||||
dm.killProcess(procName)
|
||||
|
||||
#an example manifest name to use on the cli
|
||||
# manifest = "http://" + options.remoteWebServer + "/reftests/layout/reftests/reftest-sanity/reftest.list"
|
||||
try:
|
||||
reftest.runTests(manifest, options)
|
||||
cmdlineArgs = ["-reftest", manifest]
|
||||
if options.bootstrap:
|
||||
cmdlineArgs = []
|
||||
reftest.runTests(manifest, options, cmdlineArgs)
|
||||
except:
|
||||
print "TEST-UNEXPECTED-FAIL | | exception while running reftests"
|
||||
reftest.stopWebServer(options)
|
||||
sys.exit(1)
|
||||
print "TEST-UNEXPECTED-FAIL | | exception while running reftests"
|
||||
reftest.stopWebServer(options)
|
||||
sys.exit(1)
|
||||
|
||||
reftest.stopWebServer(options)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
@ -74,8 +73,13 @@ class RefTest(object):
|
||||
path = defaultManifestPath
|
||||
return path
|
||||
|
||||
def createReftestProfile(self, options, profileDir, server='localhost'):
|
||||
"Sets up a profile for reftest."
|
||||
def createReftestProfile(self, options, profileDir, manifest, server='localhost'):
|
||||
"""
|
||||
Sets up a profile for reftest.
|
||||
'manifest' is the path to the reftest.list file we want to test with. This is used in
|
||||
the remote subclass in remotereftest.py so we can write it to a preference for the
|
||||
bootstrap extension.
|
||||
"""
|
||||
|
||||
self.automation.setupPermissionsDatabase(profileDir,
|
||||
{'allowXULXBL': [(server, True), ('<file>', True)]})
|
||||
@ -141,15 +145,18 @@ class RefTest(object):
|
||||
if profileDir:
|
||||
shutil.rmtree(profileDir, True)
|
||||
|
||||
def runTests(self, testPath, options):
|
||||
def runTests(self, testPath, options, cmdlineArgs = None):
|
||||
debuggerInfo = getDebuggerInfo(self.oldcwd, options.debugger, options.debuggerArgs,
|
||||
options.debuggerInteractive);
|
||||
|
||||
profileDir = None
|
||||
try:
|
||||
reftestlist = self.getManifestPath(testPath)
|
||||
if cmdlineArgs == None:
|
||||
cmdlineArgs = ['-reftest', reftestlist]
|
||||
profileDir = mkdtemp()
|
||||
self.copyExtraFilesToProfile(options, profileDir)
|
||||
self.createReftestProfile(options, profileDir)
|
||||
self.createReftestProfile(options, profileDir, reftestlist)
|
||||
self.installExtensionsToProfile(options, profileDir)
|
||||
|
||||
# browser environment
|
||||
@ -159,9 +166,8 @@ class RefTest(object):
|
||||
|
||||
# then again to actually run reftest
|
||||
self.automation.log.info("REFTEST INFO | runreftest.py | Running tests: start.\n")
|
||||
reftestlist = self.getManifestPath(testPath)
|
||||
status = self.automation.runApp(None, browserEnv, options.app, profileDir,
|
||||
["-reftest", reftestlist],
|
||||
cmdlineArgs,
|
||||
utilityPath = options.utilityPath,
|
||||
xrePath=options.xrePath,
|
||||
debuggerInfo=debuggerInfo,
|
||||
|
Loading…
Reference in New Issue
Block a user