Skip to content

Commit

Permalink
Webinspector: Add web inspection and automation session.
Browse files Browse the repository at this point in the history
  • Loading branch information
matan1008 committed Jan 13, 2022
1 parent 5227780 commit 926719b
Show file tree
Hide file tree
Showing 32 changed files with 1,729 additions and 38 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ each will lead to each one's implementation, where you can learn more about.
* Allows to simulate locations (DeveloperDiskImage)
* [`com.apple.dt.fetchsymbols`](pymobiledevice3/services/dtfetchsymbols.py)
* Allows fetching of `dyld` and dyld shared cache files (DeveloperDiskImage)
* [`com.apple.webinspector`](pymobiledevice3/services/webinspector.py)
* Used to debug WebViews

## Un-implemented services

Expand All @@ -218,8 +220,6 @@ to [create us an issue request](https://github.com/doronz88/pymobiledevice3/issu
* API wrapper for `notify_post()` & `notify_register_dispatch()` from whitelist
* `com.apple.mobilesync`
* `com.apple.purpletestr`
* `com.apple.webinspector`
* Used to debug WebViews

# The bits and bytes

Expand Down
3 changes: 2 additions & 1 deletion pymobiledevice3/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from pymobiledevice3.cli.restore import cli as restore_cli
from pymobiledevice3.cli.springboard import cli as springboard_cli
from pymobiledevice3.cli.syslog import cli as syslog_cli
from pymobiledevice3.cli.webinspector import cli as webinspector_cli
from pymobiledevice3.exceptions import NoDeviceConnectedError

coloredlogs.install(level=logging.INFO)
Expand All @@ -41,7 +42,7 @@ def cli():
cli_commands = click.CommandCollection(sources=[
developer_cli, mounter_cli, apps_cli, profile_cli, lockdown_cli, diagnostics_cli, syslog_cli, pcap_cli,
crash_cli, afc_cli, ps_cli, notification_cli, list_devices_cli, power_assertion_cli, springboard_cli,
provision_cli, backup_cli, restore_cli, activation_cli, companion_cli
provision_cli, backup_cli, restore_cli, activation_cli, companion_cli, webinspector_cli
])
cli_commands.context_settings = dict(help_option_names=['-h', '--help'])
try:
Expand Down
4 changes: 4 additions & 0 deletions pymobiledevice3/cli/cli_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def set_verbosity(ctx, param, value):
coloredlogs.set_level(logging.INFO - (value * 10))


def wait_return():
input('> Hit RETURN to exit')


UDID_ENV_VAR = 'PYMOBILEDEVICE3_UDID'


Expand Down
6 changes: 1 addition & 5 deletions pymobiledevice3/cli/developer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from termcolor import colored

import pymobiledevice3
from pymobiledevice3.cli.cli_common import print_json, Command, default_json_encoder
from pymobiledevice3.cli.cli_common import print_json, Command, default_json_encoder, wait_return
from pymobiledevice3.exceptions import DvtDirListError, ExtractingStackshotError
from pymobiledevice3.lockdown import LockdownClient
from pymobiledevice3.services.accessibilityaudit import AccessibilityAudit
Expand Down Expand Up @@ -42,10 +42,6 @@
logger = logging.getLogger(__name__)


def wait_return():
input('> Hit RETURN to exit')


@click.group()
def cli():
""" developer cli """
Expand Down
109 changes: 109 additions & 0 deletions pymobiledevice3/cli/webinspector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import time

import click
import IPython

from pymobiledevice3.cli.cli_common import Command, wait_return
from pymobiledevice3.exceptions import WirError
from pymobiledevice3.lockdown import LockdownClient
from pymobiledevice3.services.webinspector import WebinspectorService, SAFARI
from pymobiledevice3.services.web_protocol.driver import WebDriver, Cookie, By


@click.group()
def cli():
""" webinspector cli """
pass


@cli.group()
def webinspector():
""" webinspector options """
pass


@webinspector.command(cls=Command)
def opened_tabs(lockdown: LockdownClient):
"""
Show All opened tabs.
Opt in:
Settings -> Safari -> Advanced -> Web Inspector
"""
inspector = WebinspectorService(lockdown=lockdown)
with inspector.connect():
# Best effort.
time.sleep(1)
apps = inspector.get_open_pages()
for app_name in apps:
print(app_name)
for page in apps[app_name]:
print(f' - {page.web_url}')


@webinspector.command(cls=Command)
@click.argument('url')
def launch(lockdown: LockdownClient, url):
"""
Open a specific URL in Safari.
Opt in:
Settings -> Safari -> Advanced -> Web Inspector
Settings -> Safari -> Advanced -> Remote Automation
"""
inspector = WebinspectorService(lockdown=lockdown)
with inspector.connect():
safari = inspector.open_app(SAFARI)
with inspector.automation_session(safari) as session:
driver = WebDriver(session)
driver.start_session()
driver.get(url)
wait_return()


@webinspector.command(cls=Command)
def shell(lockdown: LockdownClient):
"""
Opt in:
Settings -> Safari -> Advanced -> Web Inspector
Settings -> Safari -> Advanced -> Remote Automation
"""
inspector = WebinspectorService(lockdown=lockdown)
with inspector.connect():
safari = inspector.open_app(SAFARI)
with inspector.automation_session(safari) as session:
driver = WebDriver(session)
IPython.embed(user_ns={
'driver': driver,
'Cookie': Cookie,
'By': By,
})


@webinspector.command(cls=Command)
@click.argument('url', required=False, default='')
def jsshell(lockdown: LockdownClient, url):
"""
Opt in:
Settings -> Safari -> Advanced -> Web Inspector
Settings -> Safari -> Advanced -> Remote Automation
"""
inspector = WebinspectorService(lockdown=lockdown)
with inspector.connect():
safari = inspector.open_app(SAFARI)
with inspector.automation_session(safari) as session:
driver = WebDriver(session)
driver.start_session()
if url:
driver.get(url)
while True:
exp = input('> ')
try:
print(driver.execute_script(f'return {exp}'))
except WirError as e:
print(e)
7 changes: 6 additions & 1 deletion pymobiledevice3/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'PasswordRequiredError', 'StartServiceError', 'FatalPairingError', 'NoDeviceConnectedError', 'MuxException',
'MuxVersionError', 'ArgumentError', 'AfcException', 'AfcFileNotFoundError', 'DvtException', 'DvtDirListError',
'NotMountedError', 'AlreadyMountedError', 'UnsupportedCommandError', 'ExtractingStackshotError',
'ConnectionTerminatedError'
'ConnectionTerminatedError', 'WirError'
]


Expand Down Expand Up @@ -115,3 +115,8 @@ class ExtractingStackshotError(PyMobileDevice3Exception):
class ConnectionTerminatedError(PyMobileDevice3Exception):
""" Raise when a connection is terminated abruptly. """
pass


class WirError(PyMobileDevice3Exception):
""" Raise when Webinspector WIR command fails. """
pass
2 changes: 2 additions & 0 deletions pymobiledevice3/resources/webinspector/element_attribute.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions pymobiledevice3/resources/webinspector/element_clear.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pymobiledevice3/resources/webinspector/enter_fullscreen.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions pymobiledevice3/resources/webinspector/find_nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pymobiledevice3/resources/webinspector/focus.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 926719b

Please sign in to comment.