Merge remote-tracking branch 'origin/pr/3333'
This commit is contained in:
commit
003ec31848
@ -22,6 +22,7 @@
|
||||
import enum
|
||||
import itertools
|
||||
|
||||
import sip
|
||||
import attr
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt
|
||||
from PyQt5.QtGui import QIcon
|
||||
@ -864,3 +865,6 @@ class AbstractTab(QWidget):
|
||||
except (AttributeError, RuntimeError) as exc:
|
||||
url = '<{}>'.format(exc.__class__.__name__)
|
||||
return utils.get_repr(self, tab_id=self.tab_id, url=url)
|
||||
|
||||
def is_deleted(self):
|
||||
return sip.isdeleted(self._widget)
|
||||
|
@ -1644,6 +1644,8 @@ class CommandDispatcher:
|
||||
"""
|
||||
try:
|
||||
elem.set_value(text)
|
||||
except webelem.OrphanedError as e:
|
||||
message.warning('Edited element vanished')
|
||||
except webelem.Error as e:
|
||||
raise cmdexc.CommandError(str(e))
|
||||
|
||||
|
@ -60,6 +60,13 @@ class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OrphanedError(Exception):
|
||||
|
||||
"""Raised when a webelement's parent has vanished."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class AbstractWebElement(collections.abc.MutableMapping):
|
||||
|
||||
"""A wrapper around QtWebKit/QtWebEngine web element.
|
||||
|
@ -100,6 +100,8 @@ class WebEngineElement(webelem.AbstractWebElement):
|
||||
|
||||
def _js_call(self, name, *args, callback=None):
|
||||
"""Wrapper to run stuff from webelem.js."""
|
||||
if self._tab.is_deleted():
|
||||
raise webelem.OrphanedError("Tab containing element vanished")
|
||||
js_code = javascript.assemble('webelem', name, self._id, *args)
|
||||
self._tab.run_js_async(js_code, callback=callback)
|
||||
|
||||
|
@ -118,6 +118,8 @@ class WebKitElement(webelem.AbstractWebElement):
|
||||
|
||||
def set_value(self, value):
|
||||
self._check_vanished()
|
||||
if self._tab.is_deleted():
|
||||
raise webelem.OrphanedError("Tab containing element vanished")
|
||||
if self.is_content_editable():
|
||||
log.webelem.debug("Filling {!r} via set_text.".format(self))
|
||||
self._elem.setPlainText(value)
|
||||
|
@ -115,6 +115,19 @@ Feature: Opening external editors
|
||||
And I run :click-element id qute-button
|
||||
Then the javascript message "text: foobar" should be logged
|
||||
|
||||
# Could not get signals working on Windows
|
||||
@posix
|
||||
Scenario: Spawning an editor and closing the tab
|
||||
When I set up a fake editor that waits
|
||||
And I open data/editor.html
|
||||
And I run :click-element id qute-textarea
|
||||
And I wait for "Entering mode KeyMode.insert (reason: clicking input)" in the log
|
||||
And I run :open-editor
|
||||
And I set tabs.last_close to blank
|
||||
And I run :tab-close
|
||||
And I kill the waiting editor
|
||||
Then the warning "Edited element vanished" should be shown
|
||||
|
||||
@qtwebengine_todo: Caret mode is not implemented yet
|
||||
Scenario: Spawning an editor in caret mode
|
||||
When I set up a fake editor returning "foobar"
|
||||
|
@ -20,6 +20,8 @@
|
||||
import sys
|
||||
import json
|
||||
import textwrap
|
||||
import os
|
||||
import signal
|
||||
|
||||
import pytest_bdd as bdd
|
||||
bdd.scenarios('editor.feature')
|
||||
@ -64,3 +66,35 @@ def set_up_editor(quteproc, server, tmpdir, text):
|
||||
def set_up_editor_empty(quteproc, server, tmpdir):
|
||||
"""Set up editor.command to a small python script inserting empty text."""
|
||||
set_up_editor(quteproc, server, tmpdir, "")
|
||||
|
||||
|
||||
@bdd.when(bdd.parsers.parse('I set up a fake editor that waits'))
|
||||
def set_up_editor_wait(quteproc, server, tmpdir):
|
||||
"""Set up editor.command to a small python script inserting a text."""
|
||||
pidfile = tmpdir / 'editor_pid'
|
||||
script = tmpdir / 'script.py'
|
||||
script.write(textwrap.dedent("""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
|
||||
with open(r'{pidfile}', 'w') as f:
|
||||
f.write(str(os.getpid()))
|
||||
|
||||
signal.signal(signal.SIGUSR1, lambda s, f: sys.exit(0))
|
||||
time.sleep(100)
|
||||
""".format(pidfile=pidfile)))
|
||||
editor = json.dumps([sys.executable, str(script), '{}'])
|
||||
quteproc.set_setting('editor.command', editor)
|
||||
|
||||
|
||||
@bdd.when(bdd.parsers.parse('I kill the waiting editor'))
|
||||
def kill_editor_wait(quteproc, server, tmpdir):
|
||||
"""Kill the waiting editor."""
|
||||
pidfile = tmpdir / 'editor_pid'
|
||||
pid = int(pidfile.read())
|
||||
# windows has no SIGUSR1, but we don't run this on windows anyways
|
||||
# for posix, there IS a member so we need to ignore useless-suppression
|
||||
# pylint: disable=no-member,useless-suppression
|
||||
os.kill(pid, signal.SIGUSR1)
|
||||
|
@ -29,7 +29,7 @@ import pytest
|
||||
from PyQt5.QtCore import QRect, QPoint, QUrl
|
||||
QWebElement = pytest.importorskip('PyQt5.QtWebKit').QWebElement
|
||||
|
||||
from qutebrowser.browser import webelem
|
||||
from qutebrowser.browser import webelem, browsertab
|
||||
from qutebrowser.browser.webkit import webkitelem
|
||||
from qutebrowser.misc import objects
|
||||
from qutebrowser.utils import usertypes
|
||||
@ -127,7 +127,9 @@ def get_webelem(geometry=None, frame=None, *, null=False, style=None,
|
||||
return style_dict[name]
|
||||
|
||||
elem.styleProperty.side_effect = _style_property
|
||||
wrapped = webkitelem.WebKitElement(elem, tab=None)
|
||||
tab = mock.Mock(autospec=browsertab.AbstractTab)
|
||||
tab.is_deleted.return_value = False
|
||||
wrapped = webkitelem.WebKitElement(elem, tab=tab)
|
||||
return wrapped
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user