I am a beginner in developing Chrome extensions. I am trying to achieve a native messaging between my extension and a C++ code. Here is the C++ code
int main(int argc, char* argv[]) {
// Define our message
char message[] = "{\"text\": \"This is a response message\"}";
// Collect the length of the message
unsigned int len = strlen(message);
// We need to send the 4 bytes of length information
printf("%c%c%c%c", (char) (len & 0xff),
(char) ((len>>8) & 0xFF),
(char) ((len>>16) & 0xFF),
(char) ((len>>24) & 0xFF));
// Now we can output our message
printf("%s", message);
return 0;
}
The problem is that the extension does receive any thing and I don't know how to debug the program. I've tried opening Chrome from the terminal so that errors are displayed, but nothing is displayed there. here is the code from the background.js
var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function(msg) {
console.log("Received" + msg);
});
port.onDisconnect.addListener(function() {
console.log("Disconnected");
});
Any way I could debug the program?
You can run Chrome with logging enabled and then review the errors using Sawbuck - a handy GUI designed just for that. If the problem is with Chrome, it might shed some light.
see here - http://www.chromium.org/for-testers/enable-logging
There are multiple ways to debug but no end-end IDE like debug exists.
to debug your background and content scripts--- background and page content section in chrome tools
to debug the host --- open chrome from terminal with logging enabled
Also native messaging API offers you some methods which will return appropriate error messages like, runtime.lastError
can refer this
Related
I need to pass certain values to my HTML from WKWebview.
Here is my code snipped of what I've tried yet.
[self.webView evaluateJavaScript:#"document.getElementById('popo_data').innerHTML = feed,OMG,BTC;" completionHandler:^(NSString *result, NSError *error) {
if(error != nil) {
NSLog(#"######## SomeFunction Error: %#",error);
return;
}
NSLog(#"######## SomeFunction Success");
}];
That does not look like well formed JavaScript, because quotes are missing around the string you're assigning to the #popo_data element. I suppose you're getting a syntax error here.
Try the following:
document.getElementById('popo_data').innerHTML = "feed,OMG,BTC"
If this does not work, you can debug your webview with Safari by connecting the debugger to your device or simulator. Safari Preferences > check "Show Develop menu in menu bar."
.pro
LIBS += -LC:\Qt\Tools\OpenSSL\Win_x86\lib -llibssl
LIBS += -LC:\Qt\Tools\OpenSSL\Win_x86\lib -llibcrypto
INCLUDEPATH += C:\Qt\Tools\OpenSSL\Win_x86\include
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 480
Component.onCompleted: getPage(logResults)
function logResults(results) {
console.log("RESULTS: " + results)
}
function getPage(callback) {
var xhttp = new XMLHttpRequest();
var url = "https://www.google.com/"
xhttp.onreadystatechange = function() {
if (xhttp.readyState === 4 && xhttp.status === 200) {
console.log("calling callback")
callback(xhttp.responseText)
}
};
xhttp.open("GET", url);
xhttp.send();
}
}
expected output
qml: calling callback
qml: RESULTS: <html>
actual output
qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_ciphersuites
qt.network.ssl: QSslSocket: cannot resolve SSL_set_psk_use_session_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_set_psk_use_session_callback
qml: calling callback
Windows 10 64-bit OS, running MSVC2017 QML project
I ran C:\Qt\MaintenanceTool.exe to install Developer and Designer Tools > OpenSSL 1.1.1d Toolkit
I've tried following a previous tutorial and another one for MSVC2017 but no luck in resolving the errors or getting xhttp.responseText. Found out the code works in ubuntu 19.4 so it just has to be that I'm running it on my windows machine that something funky is happening with the OpenSSL. I couldn't find any resolution by googling the outputted error messages. I've read that accidentally installing openSSL to "the windows directory" can cause errors, but I've not been able to actually locate "the windows directory" in question to check if I did.
edit
From C:\Qt\Tools\OpenSSL\Win_x64\bin I copied libcrypto-1_1-x64.dll and libssl-1_1-x64.dll to my project's \debug and \release folders. This removed the qt.network.ssl errors, however I am still not getting the expected output of qml: RESULTS: <html>
You ran C:\Qt\MaintenanceTool.exe to install Developer and Designer
Tools > OpenSSL 1.1.1d Toolkit
That is also my recommendation. The alternative is to compile OpenSSL yourself, or download a binary package from a third party provider. I have one of those packages installed at "C:\Program Files\OpenSSL-Win64\bin", and programs using Qt+=network are able to locate and load the libraries when their path is included in the PATH environment variable. The problem is that you will need to take care of the updates yourself, but the Qt packages are automatically updated with the MaintenanceTool along with Qt and Qt Creator. So pick your choice.
Anyway, even if you have another set of OpenSSL DLLs in your path, if you copy the libraries to the output directory of your executable, these libraries will be loaded instead. Two questions need to be answered here: 1) how do you copy the DLLs automatically each time they are needed?, and 2) how do you verify which DLLs are loaded when you run your program?
1) You may add the following to your project .pro:
win32 {
CONFIG += file_copies
CONFIG(debug, debug|release) {
openssllibs.path = $$OUT_PWD/debug
} else {
openssllibs.path = $$OUT_PWD/release
}
contains(QMAKE_TARGET.arch, x86_64) {
openssllibs.files = C:/Qt/Tools/OpenSSL/Win_x64/bin/libcrypto-1_1-x64.dll \
C:/Qt/Tools/OpenSSL/Win_x64/bin/libssl-1_1-x64.dll
} else {
openssllibs.files = C:/Qt/Tools/OpenSSL/Win_x86/bin/libcrypto-1_1.dll \
C:/Qt/Tools/OpenSSL/Win_x86/bin/libssl-1_1.dll
}
COPIES += openssllibs
}
That is it. Now your program will always have the latest libraries from Qt/Tools copied to the output directory of your project, without worrying if you compile in debug or release mode, or 32/64 bits, or another Qt Kit.
2) Run your program while inspecting the loaded DLLs with Process Explorer, by Mark Russinovich. To do so, in Process Explorer->View->Show lower pane, and select your running program in the upper pane. The lower pane lists all your loaded DLLs and origins. There are other similar utilities out there, like the open source Process Hacker.
Even understanding all of the above, and following exactly the recipe, your program still does not print the desired output. Please change the function logResults() in your qml like this:
function logResults(results) {
console.log("RESULTS Length=", results.length);
console.log("results.substr=", results.substr(0, 20));
}
You will get the following output:
qml: calling callback
qml: RESULTS Length= 47932
qml: results.substr= <!doctype html><html
Explanation: looks like console.log() has a limitation of about 32K in Windows (it doesn't on Linux). The document retrieved from the remote host is much larger, and this breaks the logging function. This is probably a bug in Qt (it should not fail silently like that).
Another advice for anybody coming here in the future: It is not strictly needed, but you may want to verify in your main() function that SSL is available, with something like this code:
#include <QDebug>
#include <QSslSocket>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
if (!QSslSocket::supportsSsl()) {
qDebug() << "Sorry, OpenSSL is not supported";
return -1;
}
qDebug() << "build-time OpenSSL version:" << QSslSocket::sslLibraryBuildVersionString();
qDebug() << "run-time OpenSSL version:" << QSslSocket::sslLibraryVersionString();
[...]
}
I am trying to create a minimal POC of evaluating javascript using using QtWebEngine and no GUI involved.
One attempt
int main(void)
{
int argc = 1;
char *argv[] = {"Hello"};
QApplication app(argc, argv);;
QtWebEngine *e = QtWebEngine::initialize()
QWebEnginePage *page = new QWebEnginePage;
page->runJavaScript("'Java''' 'Script'",
[](const QVariant &result){ qDebug() << result; });
std::cout << "Compiled and Linked" << std::endl;
return 0;
}
but this errored with a display not attached error, something to do with guis I take it.
I also found something about the distinction of console app and gui app, but it was not clear to me and I tried using variantions of
QCoreApplication *app = QCoreApplication::instance();
but this also erred.
I also ran into the issue of
:[0712/072409:ERROR:browser_main_loop.cc(217)] Running without the
SUID sandbox! See
https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md
for more information on developing with the sandbox on.
and apparently --disable-setuid-sandbox to chromium is an escape hatch but I'm not quite clear where I could set that programmatically.
I have started looking at tutorials for making TVML/TVJS based apps for the new Apple TV, and I have two problems that makes the development process very tedious and impractical.
First thing I am having trouble understanding is how I am supposed to debug code that happens on startup of the application. I have connected the Safari debugger, and I do manage to hit some breakpoints, but only for code that is triggered by some user input. On startup I am loading an xml document from a remote location, and I will use this to dynamically generate the tvml template, but I cannot get the debugger to stop anywhere in the code that is running before the template is done rendering.
The other anti-productive problem I have is that I cannot seem to reload the JavaScript files in any other way than completely shutting down the application in the simulator (double-click the home button, and swipe the app away). This also makes the debugger quit, so I have to restart that one as well. This surely cannot be the way you are supposed to do continuous development and testing?
You can make the debugger stop at the first line when you choose the Auto Pause and Auto Show options from the Safari menu "Develop/Simulator".
You are correct about the exit issue.
One thing you can also try is to run App.reload() from the Safari Debugger console.
This also restarts the app, maybe in the future they can make it work so the debugger will not be gone.
But at the moment this also does not solve the issue.
For manual debugger output (aka console.log()), you could redirect the logging to the Xcode debugger.
(somewhere on the web) I found a way to actually do that, in short it looks like...
AppDelegate.Swift
func appController(appController: TVApplicationController, evaluateAppJavaScriptInContext jsContext: JSContext) {
let jsInterface: cJsInterface = cJsInterface();
jsContext.setObject(jsInterface, forKeyedSubscript: "swiftInterface")
}
App.js
// re-route console.log() to XCode debug window
var console = {
log: function() {
var message = '';
for(var i = 0; i < arguments.length; i++) {
message += arguments[i] + ' '
};
swiftInterface.log(message)
}
};
JsInterface.Swift
#objc protocol jsInterfaceProtocol : JSExport {
func log(message: String) -> Void
}
...
class cJsInterface: NSObject, jsInterfaceProtocol {
func log(message: String) -> Void {
print("JS: \(message)")
}
}
Complete sources in github: https://github.com/iBaa/PlexConnectApp/tree/f512dfd9c1cb2fbfed2da43c4e3837435b0b22af
I don't have any solution for the dying debugger myself...
I am experiencing some different javascript behavior when running my site on Kindle Fire than through Chrome. In order to debug this I need access to something like the Chrome Developer Tool or Firebug. Any suggestions?
In the same boat here... was hoping adb logcat would help, but javascript console messages don't seem to appear there. Perhaps there's something that needs to be set on the device to direct console logs to logcat?
edit: found a decent solution: http://jsconsole.com -- allows you to set up a remote debug/logging console. Pretty simple (console logging only, so you'll need to dump a lot of into into the logs)... but it works well. Helped me track down the source of my issues, at least!
how-to: http://jsconsole.com/remote-debugging.html
I took a different approach and created a wrapper native app that pop up a dialog for JavaScript.
My wrapper code is rather large, so I took a snippet of the relavant parts. It actually works and will display ANY javascript error.
// registers the debugger to catch errors
WebView engine = (WebView) findViewById(R.id.web_engine);
engine.setWebChromeClient(new DebugClient(this));
// the class that manages the errors
private class DebugClient extends WebChromeClient {
Activity activity;
public DebugClient(Activity activity) {
this.activity = activity;
}
#Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
if (consoleMessage.messageLevel() == MessageLevel.ERROR
|| consoleMessage.messageLevel() == MessageLevel.WARNING) {
String title="Javascript error on line "
+ String.valueOf(consoleMessage.lineNumber())
+ " of " + consoleMessage.sourceId();
AlertBox alertBox=new AlertBox(activity, (ActionListener)null, title, consoleMessage.message(), "OK");
alertBox.show();
alertBoxes.add(alertBox);
}
return true;
}
}
To compile this, you'll need to install the Android SDK on your computer, and probably a Java IDE (Eclipse?) with ADT. Then you just do: create new project, add a WebView component into your layout/main.xml, and paste the code. Compile and install on your Kindle Fire.