I am writing a small application using Qt
and QML
that uses the example in the Qt documentation WebEngine Quick Nano Browser.
In this example I am trying to access to my email. I can do it, but I am trying to enter username and password automatically so that I can instantly log into my emails.
Basically as an example, after launching the application (my email address is hard-coded) I can see the username
page of gmail
, but here I have to type my username to access to the next page that has the password
::
Here I have to type my password
:
Only after doing that I can access to my email.
The Expected result would be as soon as I run the application, I would like to go straight to my email without inputting username
and password
The code that I am running is the following:
#include <QtGui/QGuiApplication>
typedef QGuiApplication Application;
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtWebEngine/qtwebengineglobal.h>
static QUrl startupUrl()
{
QUrl ret;
QStringList args(qApp->arguments());
args.takeFirst();
for (const QString &arg : qAsConst(args)) {
if (arg.startsWith(QLatin1Char('-')))
continue;
ret = Utils::fromUserInput(arg);
if (ret.isValid())
return ret;
}
// first email
return QUrl(QStringLiteral("https://accounts.google.com/signin"));
}
int main(int argc, char **argv)
{
QCoreApplication::setOrganizationName("QtExamples");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
Application app(argc, argv);
QtWebEngine::initialize();
QQmlApplicationEngine appEngine;
Utils utils;
appEngine.rootContext()->setContextProperty("utils", &utils);
appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));
return app.exec();
}
What I tried so far
I have beed doing a lot of research and this source was useful in trying to understand the concept on how to hard code the entries. However, how do I proceed to the next passowrd
page`?
This is another example (although in php
) of the same problem with a different approach. That also was useful to undertand the concept and the main idea.
this additional source looks a very good example, although JavaScript
is used here.
Now after reading much more information I found this post which makes me think that the best approach would be to integrate some JavaScript
inside the QML
code? I am a newbie in JavaScript
if that would be the right route. And if this is the right thing, how can I do that?
I am considering to use QNetworkAccessManager in this application, but I am not sure how to best implement it.
Thanks to anyone who may have already gone through this or that may provide some guidance or an example to how implement this in the WebEngine Quick Nano Browser
is very appreciated.
Do not use the example WebEngine Quick Nano Browser as I see it unnecessary and only distract from the background objective.
The logic is to understand how google login works, in this case you must find a way to obtain the elements of the DOM using javascript for example through id, class, name, etc. and modify it according to the desired logic. Also note that the url changes so that in each one a different script must be executed.
Considering the above, the solution is:
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtWebEngine 1.9
ApplicationWindow{
id: root
width: 640
height: 480
visible: true
property string username: "USERNAME"
property string password: "PASSWORD"
QtObject{
id: internals
property string script_username: "
setTimeout(function() {
var input_username = document.getElementById('identifierId');
input_username.value = '%1';
var button = document.getElementById('identifierNext');
button.click();
}, 1000);
".arg(username)
property string script_password: "
setTimeout(function() {
var input_password = document.getElementsByName('password')[0];
input_password.value = '%1';
var button = document.getElementById('passwordNext');
button.click();
}, 1000);
".arg(password)
}
WebEngineView {
id: view
anchors.fill: parent
onUrlChanged: {
if(url == "https://accounts.google.com/signin/v2/identifier?flowName=GlifWebSignIn&flowEntry=ServiceLogin"){
view.runJavaScript(internals.script_username)
}
else if(url == "https://accounts.google.com/signin/v2/sl/pwd?flowName=GlifWebSignIn&flowEntry=ServiceLogin&cid=1&navigationDirection=forward"){
view.runJavaScript(internals.script_password)
}
}
Component.onCompleted: view.url = "https://accounts.google.com/signin"
}
}