[epiphany/mcatanzaro/automation] WIP: add support for automation mode



commit 3f442f0f0832ba7d326924e19d6d3d690f79240f
Author: Michael Catanzaro <mcatanzaro igalia com>
Date:   Tue Jan 1 20:00:26 2019 -0600

    WIP: add support for automation mode
    
    Next step: learn how to use automation mode, so I can test if it
    actually works.
    
    Note: you probably want --automation-mode -p as otherwise you won't get
    a private profile. I wasn't sure whether to prohibit automation in
    browser and application mode, and making automation totally separate from
    the EphyEmbedShellMode seemed easiest. So pass -p if you need it!

 data/epiphany.1          |  3 +++
 embed/ephy-embed-shell.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 embed/ephy-embed-shell.h |  6 +++++-
 embed/ephy-web-view.c    | 18 ++++++++++++++++++
 embed/ephy-web-view.h    |  3 ++-
 meson.build              |  5 +++++
 src/ephy-main.c          |  5 +++++
 src/ephy-shell.c         | 14 ++++++++++++++
 src/ephy-shell.h         |  5 ++++-
 9 files changed, 102 insertions(+), 5 deletions(-)
---
diff --git a/data/epiphany.1 b/data/epiphany.1
index 1b835b981..8cfb374d9 100644
--- a/data/epiphany.1
+++ b/data/epiphany.1
@@ -37,6 +37,9 @@ Start a private instance (temporary profile directory, not private browsing mode
 \fB\-\-incognito\-mode\fR
 Start a private instance in incognito mode
 .TP
+\fB\-\-automation\-mode\fR
+Start the browser in automation mode, for WebDriver control
+.TP
 \fB\-\-profile\fR=\fIFILE\fR
 Profile directory to use in the private instance
 .TP
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 75d565941..fbb7dacef 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -1427,8 +1427,7 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
     g_signal_new ("window-restored",
                   EPHY_TYPE_EMBED_SHELL,
                   G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (EphyEmbedShellClass, restored_window),
-                  NULL, NULL, NULL,
+                  0, NULL, NULL, NULL,
                   G_TYPE_NONE,
                   0);
 
@@ -1725,6 +1724,51 @@ ephy_embed_shell_clear_cache (EphyEmbedShell *shell)
   webkit_web_context_clear_cache (priv->web_context);
 }
 
+static WebKitWebView *
+automation_create_web_view_cb (WebKitAutomationSession *session,
+                               EphyEmbedShell          *shell)
+{
+  EphyEmbed *new_embed = EPHY_EMBED_SHELL_GET_CLASS (shell)->create_automated_tab (shell);
+
+  return WEBKIT_WEB_VIEW (ephy_embed_get_web_view (new_embed));
+}
+
+static void
+automation_started_cb (WebKitWebContext        *context,
+                       WebKitAutomationSession *session,
+                       EphyEmbedShell          *shell)
+{
+  WebKitApplicationInfo *info = webkit_application_info_new ();
+  webkit_application_info_set_name (info, "Epiphany");
+  webkit_application_info_set_version (info, EPHY_MAJOR_VERSION, EPHY_MINOR_VERSION, EPHY_MICRO_VERSION);
+  webkit_automation_session_set_application_info (session, info);
+  webkit_application_info_unref (info);
+
+  g_signal_connect_object (session, "create-web-view",
+                           G_CALLBACK (automation_create_web_view_cb), shell, 0);
+}
+
+void
+ephy_embed_shell_enable_automation (EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  g_assert (priv->web_context);
+  g_assert (!webkit_web_context_is_automation_allowed (priv->web_context));
+
+  webkit_web_context_set_automation_allowed (priv->web_context, TRUE);
+  g_signal_connect_object (priv->web_context, "automation-started",
+                           G_CALLBACK (automation_started_cb), shell, 0);
+}
+
+gboolean
+ephy_embed_shell_is_automation_enabled (EphyEmbedShell *shell)
+{
+  EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+
+  return webkit_web_context_is_automation_allowed (priv->web_context);
+}
+
 WebKitUserContentManager *
 ephy_embed_shell_get_user_content_manager (EphyEmbedShell *shell)
 {
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index cf7cf557b..96dba4955 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -38,6 +38,8 @@ G_BEGIN_DECLS
 
 G_DECLARE_DERIVABLE_TYPE (EphyEmbedShell, ephy_embed_shell, EPHY, EMBED_SHELL, DzlApplication)
 
+typedef struct _EphyEmbed EphyEmbed;
+
 typedef enum
 {
   EPHY_EMBED_SHELL_MODE_BROWSER,
@@ -53,7 +55,7 @@ struct _EphyEmbedShellClass
 {
   DzlApplicationClass parent_class;
 
-  void    (* restored_window)  (EphyEmbedShell *shell);
+  EphyEmbed * (* create_automated_tab) (EphyEmbedShell *shell);
 };
 
 EphyEmbedShell    *ephy_embed_shell_get_default                (void);
@@ -81,6 +83,8 @@ void               ephy_embed_shell_set_thumbnail_path         (EphyEmbedShell
                                                                 const char       *path);
 void               ephy_embed_shell_schedule_thumbnail_update  (EphyEmbedShell   *shell,
                                                                 EphyHistoryURL   *url);
+void               ephy_embed_shell_enable_automation          (EphyEmbedShell *shell);
+gboolean           ephy_embed_shell_is_automation_enabled      (EphyEmbedShell *shell);
 WebKitUserContentManager *ephy_embed_shell_get_user_content_manager (EphyEmbedShell *shell);
 EphyDownloadsManager     *ephy_embed_shell_get_downloads_manager    (EphyEmbedShell *shell);
 EphyPermissionsManager   *ephy_embed_shell_get_permissions_manager  (EphyEmbedShell *shell);
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 8aa412149..aec16a0cb 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -2901,11 +2901,29 @@ ephy_web_view_new (void)
                        NULL);
 }
 
+GtkWidget *
+ephy_web_view_new_automated (void)
+{
+  EphyEmbedShell *shell = ephy_embed_shell_get_default ();
+
+  g_assert (ephy_embed_shell_is_automation_enabled (shell));
+
+  return g_object_new (EPHY_TYPE_WEB_VIEW,
+                       "web-context", ephy_embed_shell_get_web_context (shell),
+                       "user-content-manager", ephy_embed_shell_get_user_content_manager (shell),
+                       "settings", ephy_embed_prefs_get_settings (),
+                       "is-controlled-by-automation", TRUE,
+                       NULL);
+}
+
 GtkWidget *
 ephy_web_view_new_with_related_view (WebKitWebView *related_view)
 {
   EphyEmbedShell *shell = ephy_embed_shell_get_default ();
 
+  /* Note: web-context and is-controlled-by-automation are automatically
+   * set from the related view.
+   */
   return g_object_new (EPHY_TYPE_WEB_VIEW,
                        "related-view", related_view,
                        "user-content-manager", ephy_embed_shell_get_user_content_manager (shell),
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index dfc909f33..10947cdf3 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -77,7 +77,8 @@ typedef void (* EphyPasswordSaveRequestCallback) (int      response_id,
 GType                      ephy_web_view_chrome_get_type          (void);
 GType                      ephy_web_view_security_level_get_type  (void);
 GtkWidget *                ephy_web_view_new                      (void);
-GtkWidget                 *ephy_web_view_new_with_related_view    (WebKitWebView             *related_view);
+GtkWidget *                ephy_web_view_new_automated            (void);
+GtkWidget *                ephy_web_view_new_with_related_view    (WebKitWebView             *related_view);
 void                       ephy_web_view_load_request             (EphyWebView               *view,
                                                                    WebKitURIRequest          *request);
 void                       ephy_web_view_load_url                 (EphyWebView               *view,
diff --git a/meson.build b/meson.build
index 29e266b27..b50bb4f40 100644
--- a/meson.build
+++ b/meson.build
@@ -49,6 +49,11 @@ conf.set10('TECH_PREVIEW', tech_preview)
 
 conf.set_quoted('VERSION', meson.project_version())
 
+version_array = meson.project_version().split('.')
+conf.set('EPHY_MAJOR_VERSION', version_array[0].to_int())
+conf.set('EPHY_MINOR_VERSION', version_array[1].to_int())
+conf.set('EPHY_MICRO_VERSION', version_array[2].to_int())
+
 configure_file(
   output: 'config.h',
   configuration: conf
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 18bb07e37..ce00eb115 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -57,6 +57,7 @@ static char *application_to_delete = NULL;
 static gboolean private_instance = FALSE;
 static gboolean incognito_mode = FALSE;
 static gboolean application_mode = FALSE;
+static gboolean automation_mode = FALSE;
 static char *desktop_file_basename = NULL;
 static char *profile_directory = NULL;
 
@@ -128,6 +129,8 @@ static const GOptionEntry option_entries[] =
   { "application-mode", 'a', G_OPTION_FLAG_FILENAME | G_OPTION_FLAG_OPTIONAL_ARG,
     G_OPTION_ARG_CALLBACK, application_mode_cb,
     N_("Start the browser in application mode"), NULL },
+  { "automation-mode", 0, 0, G_OPTION_ARG_NONE, &automation_mode,
+    N_("Start the browser in automation mode"), NULL },
   { "profile", 0, 0, G_OPTION_ARG_STRING, &profile_directory,
     N_("Profile directory to use in the private instance"), N_("DIR") },
   { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments,
@@ -179,6 +182,8 @@ get_startup_flags (void)
     flags |= EPHY_STARTUP_NEW_TAB;
   if (open_in_new_window)
     flags |= EPHY_STARTUP_NEW_WINDOW;
+  if (automation_mode)
+    flags |= EPHY_STARTUP_AUTOMATION_MODE;
 
   return flags;
 }
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 8684ee63f..657e34a97 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -70,6 +70,7 @@ static EphyShell *ephy_shell = NULL;
 
 static void ephy_shell_dispose (GObject *object);
 static void ephy_shell_finalize (GObject *object);
+static EphyEmbed *ephy_shell_create_automated_tab (EphyEmbedShell *shell);
 
 G_DEFINE_TYPE (EphyShell, ephy_shell, EPHY_TYPE_EMBED_SHELL)
 
@@ -665,6 +666,7 @@ ephy_shell_class_init (EphyShellClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
+  EphyEmbedShellClass *embed_class = EPHY_EMBED_SHELL_CLASS (klass);
 
   object_class->dispose = ephy_shell_dispose;
   object_class->finalize = ephy_shell_finalize;
@@ -674,6 +676,8 @@ ephy_shell_class_init (EphyShellClass *klass)
   application_class->activate = ephy_shell_activate;
   application_class->before_emit = ephy_shell_before_emit;
   application_class->add_platform_data = ephy_shell_add_platform_data;
+
+  embed_class->create_automated_tab = ephy_shell_create_automated_tab;
 }
 
 static void
@@ -796,6 +800,8 @@ ephy_shell_new_tab_full (EphyShell      *shell,
 
   if (related_view)
     web_view = ephy_web_view_new_with_related_view (related_view);
+  else if (flags & EPHY_NEW_TAB_AUTOMATED)
+    web_view = ephy_web_view_new_automated ();
   else
     web_view = ephy_web_view_new ();
 
@@ -837,6 +843,14 @@ ephy_shell_new_tab (EphyShell      *shell,
                                   0);
 }
 
+static EphyEmbed *
+ephy_shell_create_automated_tab (EphyEmbedShell *embed_shell)
+{
+  EphyShell *shell = EPHY_SHELL (embed_shell);
+
+  return ephy_shell_new_tab (shell, NULL, NULL, EPHY_NEW_TAB_AUTOMATED);
+}
+
 /**
  * ephy_shell_get_session:
  * @shell: the #EphyShell
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index cf8564b54..7438ecf51 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -53,6 +53,7 @@ G_DECLARE_FINAL_TYPE (EphyShell, ephy_shell, EPHY, SHELL, EphyEmbedShell)
  * @EPHY_NEW_TAB_FROM_EXTERNAL: tries to open the new tab in the current
  *        active tab if it is currently not loading anything and is
  *        blank.
+ * @EPHY_NEW_TAB_AUTOMATED: the new tab will be controlled by WebDriver
  *
  * Controls how new tabs/windows are created and handled.
  */
@@ -64,12 +65,14 @@ typedef enum {
   EPHY_NEW_TAB_FIRST        = 1 << 1,
   EPHY_NEW_TAB_APPEND_LAST  = 1 << 2,
   EPHY_NEW_TAB_APPEND_AFTER = 1 << 3,
-  EPHY_NEW_TAB_JUMP   = 1 << 4,
+  EPHY_NEW_TAB_JUMP         = 1 << 4,
+  EPHY_NEW_TAB_AUTOMATED    = 1 << 5,
 } EphyNewTabFlags;
 
 typedef enum {
   EPHY_STARTUP_NEW_TAB          = 1 << 0,
   EPHY_STARTUP_NEW_WINDOW       = 1 << 1,
+  EPHY_STARTUP_AUTOMATION_MODE  = 1 << 2,
 } EphyStartupFlags;
 
 typedef struct {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]