Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions tests/keywords/test_keyevent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
import mock

from AppiumLibrary.keywords._keyevent import _KeyeventKeywords


class KeyeventKeywordsTests(unittest.TestCase):
"""Tests for _KeyeventKeywords class."""

def setUp(self):
"""Set up the test fixture."""
self.ke = _KeyeventKeywords()
self.mock_driver = mock.Mock()
self.ke._current_application = mock.Mock(return_value=self.mock_driver)

def test_press_keycode(self):
"""Test press_keycode sends keycode to driver."""
self.ke.press_keycode(66) # KEYCODE_ENTER
self.mock_driver.press_keycode.assert_called_once_with(66, None)

def test_press_keycode_with_metastate(self):
"""Test press_keycode with meta state."""
self.ke.press_keycode(66, metastate=1) # Shift pressed
self.mock_driver.press_keycode.assert_called_once_with(66, 1)

def test_press_keycode_shift_alt(self):
"""Test press_keycode with Shift+Alt meta state."""
self.ke.press_keycode(29, metastate=3) # KEYCODE_A with Shift+Alt
self.mock_driver.press_keycode.assert_called_once_with(29, 3)

def test_long_press_keycode(self):
"""Test long_press_keycode sends long press to driver."""
self.ke.long_press_keycode(66)
self.mock_driver.long_press_keycode.assert_called_once_with(66, None)

def test_long_press_keycode_with_metastate(self):
"""Test long_press_keycode with meta state."""
self.ke.long_press_keycode(66, metastate=2) # Alt pressed
self.mock_driver.long_press_keycode.assert_called_once_with(66, 2)

def test_long_press_keycode_converts_string_to_int(self):
"""Test that long_press_keycode converts string keycode to int."""
self.ke.long_press_keycode('66')
self.mock_driver.long_press_keycode.assert_called_once_with(66, None)


if __name__ == '__main__':
unittest.main()
90 changes: 90 additions & 0 deletions tests/keywords/test_runonfailure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import unittest
import mock

from AppiumLibrary.keywords._runonfailure import _RunOnFailureKeywords


class RunOnFailureKeywordsTests(unittest.TestCase):
"""Tests for _RunOnFailureKeywords class."""

def setUp(self):
"""Set up the test fixture."""
self.rof = _RunOnFailureKeywords()
self.rof._info = mock.Mock()
self.rof._warn = mock.Mock()

def test_initial_state(self):
"""Test that initial state has no keyword registered."""
self.assertIsNone(self.rof._run_on_failure_keyword)
self.assertFalse(self.rof._running_on_failure_routine)

def test_register_keyword_returns_nothing_when_no_previous_keyword(self):
"""Test that registering a keyword returns 'Nothing' when no previous keyword was set."""
result = self.rof.register_keyword_to_run_on_failure("Log Source")
self.assertEqual(result, "Nothing")

def test_register_keyword_sets_new_keyword(self):
"""Test that registering a keyword properly sets the new keyword."""
self.rof.register_keyword_to_run_on_failure("Log Source")
self.assertEqual(self.rof._run_on_failure_keyword, "Log Source")

def test_register_keyword_returns_previous_keyword(self):
"""Test that registering a keyword returns the previously registered keyword."""
self.rof.register_keyword_to_run_on_failure("Log Source")
result = self.rof.register_keyword_to_run_on_failure("Capture Page Screenshot")
self.assertEqual(result, "Log Source")

def test_register_nothing_disables_run_on_failure(self):
"""Test that registering 'Nothing' disables the run-on-failure functionality."""
self.rof.register_keyword_to_run_on_failure("Log Source")
self.rof.register_keyword_to_run_on_failure("Nothing")
self.assertIsNone(self.rof._run_on_failure_keyword)

def test_register_nothing_case_insensitive(self):
"""Test that 'nothing' keyword is case insensitive."""
self.rof.register_keyword_to_run_on_failure("Log Source")
self.rof.register_keyword_to_run_on_failure("NOTHING")
self.assertIsNone(self.rof._run_on_failure_keyword)

def test_register_nothing_with_whitespace(self):
"""Test that 'nothing' keyword handles whitespace."""
self.rof.register_keyword_to_run_on_failure("Log Source")
self.rof.register_keyword_to_run_on_failure(" nothing ")
self.assertIsNone(self.rof._run_on_failure_keyword)

def test_run_on_failure_does_nothing_when_no_keyword_registered(self):
"""Test that _run_on_failure does nothing when no keyword is registered."""
self.rof._run_on_failure()
# Should not raise and should return early
self.assertFalse(self.rof._running_on_failure_routine)

def test_run_on_failure_does_not_run_when_already_running(self):
"""Test that _run_on_failure does not run when already running."""
self.rof._run_on_failure_keyword = "Some Keyword"
self.rof._running_on_failure_routine = True
# Should return early without changing state
self.rof._run_on_failure()
self.assertTrue(self.rof._running_on_failure_routine)

def test_run_on_failure_error_with_warn_method(self):
"""Test that _run_on_failure_error uses _warn when available."""
self.rof._run_on_failure_keyword = "Test Keyword"
self.rof._run_on_failure_error("Test error")
self.rof._warn.assert_called_once()
call_args = self.rof._warn.call_args[0][0]
self.assertIn("Test Keyword", call_args)
self.assertIn("Test error", call_args)

def test_run_on_failure_error_raises_when_no_warn_method(self):
"""Test that _run_on_failure_error raises exception when _warn not available."""
# Remove the _warn attribute
del self.rof._warn
self.rof._run_on_failure_keyword = "Test Keyword"
with self.assertRaises(Exception) as context:
self.rof._run_on_failure_error("Test error")
self.assertIn("Test Keyword", str(context.exception))
self.assertIn("Test error", str(context.exception))


if __name__ == '__main__':
unittest.main()
83 changes: 83 additions & 0 deletions tests/keywords/test_screenrecord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import unittest
import mock

from AppiumLibrary.keywords._screenrecord import _ScreenrecordKeywords


class ScreenrecordKeywordsTests(unittest.TestCase):
"""Tests for _ScreenrecordKeywords class."""

def setUp(self):
"""Set up the test fixture."""
self.sr = _ScreenrecordKeywords()
self.mock_driver = mock.Mock()
self.sr._current_application = mock.Mock(return_value=self.mock_driver)
self.sr._html = mock.Mock()
self.sr._get_log_dir = mock.Mock(return_value='/tmp/logs')
# Mock platform detection
self.sr._set_output_format = mock.Mock(return_value='mp4')

def test_initial_state(self):
"""Test initial state of screen recorder."""
sr = _ScreenrecordKeywords()
self.assertEqual(sr._screenrecord_index, 0)
self.assertIsNone(sr._recording)
self.assertIsNone(sr._output_format)

def test_start_screen_recording(self):
"""Test starting screen recording."""
self.sr.start_screen_recording()
self.mock_driver.start_recording_screen.assert_called_once()

def test_start_screen_recording_with_time_limit(self):
"""Test starting screen recording with time limit."""
self.sr.start_screen_recording(timeLimit='60s')
call_kwargs = self.mock_driver.start_recording_screen.call_args[1]
self.assertEqual(call_kwargs['timeLimit'], 60)

def test_start_screen_recording_with_options(self):
"""Test starting screen recording with additional options."""
self.sr.start_screen_recording(timeLimit='60s', bitRate=4000000)
call_kwargs = self.mock_driver.start_recording_screen.call_args[1]
self.assertEqual(call_kwargs['timeLimit'], 60)
self.assertEqual(call_kwargs['bitRate'], 4000000)

def test_start_screen_recording_does_not_restart_if_already_recording(self):
"""Test that starting screen recording doesn't restart if already recording."""
self.sr._recording = 'existing_recording'
self.sr.start_screen_recording()
self.mock_driver.start_recording_screen.assert_not_called()

def test_stop_screen_recording_without_active_session_raises(self):
"""Test stopping screen recording without active session raises error."""
with self.assertRaises(RuntimeError) as context:
self.sr.stop_screen_recording()
self.assertIn('no Active Screen Record Session', str(context.exception))

def test_stop_screen_recording_with_active_session(self):
"""Test stopping screen recording with active session."""
self.sr._recording = 'active_recording'
self.sr._output_format = 'mp4'
self.mock_driver.stop_recording_screen.return_value = 'base64videodata'
self.sr._save_recording = mock.Mock(return_value='/tmp/logs/recording.mp4')

result = self.sr.stop_screen_recording(filename='recording')

self.mock_driver.stop_recording_screen.assert_called_once()
self.sr._save_recording.assert_called_once()

def test_stop_screen_recording_with_options(self):
"""Test stopping screen recording with upload options."""
self.sr._recording = 'active_recording'
self.sr._output_format = 'mp4'
self.mock_driver.stop_recording_screen.return_value = 'base64videodata'
self.sr._save_recording = mock.Mock(return_value='/tmp/logs/recording.mp4')

self.sr.stop_screen_recording(filename='recording', remotePath='http://server/upload')

call_kwargs = self.mock_driver.stop_recording_screen.call_args[1]
self.assertEqual(call_kwargs['remotePath'], 'http://server/upload')


if __name__ == '__main__':
unittest.main()
69 changes: 69 additions & 0 deletions tests/keywords/test_screenshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import unittest
import mock
import os

from AppiumLibrary.keywords._screenshot import _ScreenshotKeywords


class ScreenshotKeywordsTests(unittest.TestCase):
"""Tests for _ScreenshotKeywords class."""

def setUp(self):
"""Set up the test fixture."""
self.ss = _ScreenshotKeywords()
self.mock_driver = mock.Mock()
self.ss._current_application = mock.Mock(return_value=self.mock_driver)
self.ss._html = mock.Mock()
self.ss._get_log_dir = mock.Mock(return_value='/tmp/logs')

def test_capture_page_screenshot_without_filename_returns_none(self):
"""Test that capturing screenshot without filename returns None."""
self.mock_driver.get_screenshot_as_base64.return_value = 'base64data'
result = self.ss.capture_page_screenshot()
self.assertIsNone(result)

def test_capture_page_screenshot_without_filename_embeds_base64(self):
"""Test that capturing screenshot without filename embeds base64 image."""
self.mock_driver.get_screenshot_as_base64.return_value = 'base64data'
self.ss.capture_page_screenshot()
self.ss._html.assert_called_once()
call_args = self.ss._html.call_args[0][0]
self.assertIn('base64data', call_args)
self.assertIn('data:image/png;base64', call_args)

def test_capture_page_screenshot_with_filename_returns_path(self):
"""Test that capturing screenshot with filename returns the path."""
result = self.ss.capture_page_screenshot('screenshot.png')
expected_path = os.path.join('/tmp/logs', 'screenshot.png')
self.assertEqual(result, expected_path)

def test_capture_page_screenshot_with_filename_saves_to_file(self):
"""Test that capturing screenshot with filename saves to file."""
self.ss.capture_page_screenshot('screenshot.png')
expected_path = os.path.join('/tmp/logs', 'screenshot.png')
self.mock_driver.get_screenshot_as_file.assert_called_once_with(expected_path)

def test_capture_page_screenshot_uses_save_screenshot_fallback(self):
"""Test that save_screenshot is used if get_screenshot_as_file not available."""
del self.mock_driver.get_screenshot_as_file
self.ss.capture_page_screenshot('screenshot.png')
expected_path = os.path.join('/tmp/logs', 'screenshot.png')
self.mock_driver.save_screenshot.assert_called_once_with(expected_path)

def test_capture_page_screenshot_with_subdirectory(self):
"""Test capturing screenshot to a subdirectory."""
result = self.ss.capture_page_screenshot('screenshots/test.png')
expected_path = os.path.join('/tmp/logs', 'screenshots', 'test.png')
self.assertEqual(result, expected_path)

def test_capture_page_screenshot_embeds_html_link(self):
"""Test that screenshot with filename embeds HTML link."""
self.ss.capture_page_screenshot('screenshot.png')
self.ss._html.assert_called_once()
call_args = self.ss._html.call_args[0][0]
self.assertIn('href=', call_args)
self.assertIn('img src=', call_args)


if __name__ == '__main__':
unittest.main()
Loading