From c83d6ef37a48355bf16383a92bea7f52b165b562 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 11:33:41 -0300 Subject: [PATCH 1/8] delete test.py file --- AppiumFlutterLibrary/keywords/test.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 AppiumFlutterLibrary/keywords/test.py diff --git a/AppiumFlutterLibrary/keywords/test.py b/AppiumFlutterLibrary/keywords/test.py deleted file mode 100644 index 1207936..0000000 --- a/AppiumFlutterLibrary/keywords/test.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -from appium.webdriver import Remote -from appium_flutter_finder import FlutterElement, FlutterFinder - -driver = Remote('http://localhost:4723/wd/hub', dict( - platformName='android', - automationName='flutter', - udid='emulator-5554', - app='/home/igortavtib/Projects/platform-mobile/app-prod-debug.apk' -)) - -finder = FlutterFinder() - -key_finder = finder.by_value_key('input-user') -input_element = FlutterElement(driver, key_finder) -driver.execute_script('flutter:waitFor', input_element) -input_element.send_keys('Teste 123') - From 235ad4d575441b311874cc8db4bfeaadca759f18 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 12:09:18 -0300 Subject: [PATCH 2/8] feat: Element verifiers --- AppiumFlutterLibrary/keywords/_element.py | 40 +++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/AppiumFlutterLibrary/keywords/_element.py b/AppiumFlutterLibrary/keywords/_element.py index a437900..c1a00e0 100644 --- a/AppiumFlutterLibrary/keywords/_element.py +++ b/AppiumFlutterLibrary/keywords/_element.py @@ -1,6 +1,5 @@ -import time from .keywordgroup import KeywordGroup -from AppiumFlutterLibrary.finder import ElementFinder +from AppiumFlutterLibrary.finder import ElementFinder, elementfinder def isstr(s): return isinstance(s, str) @@ -10,12 +9,41 @@ def __init__(self): self._element_finder = ElementFinder() def input_text(self, locator, text): - application = self._current_application() - element = self._element_finder.find(application, locator) + element = self._find_element(locator) self._info("Typing text '%s' into component '%s'" % (text, locator)) element.send_keys(text) def click_element(self, locator): - application = self._current_application() - element = self._element_finder.find(application, locator) + element = self._find_element(locator) + self._info("Clicking on element %s" % locator) element.click() + + def element_should_be_visible(self, locator): + if not self._find_element(locator).is_displayed(): + raise AssertionError("Element '%s' should be visible but not" % locator) + + def element_should_be_enabled(self, locator): + if not self._find_element(locator).is_enabled(): + raise AssertionError("Element '%s' should be enabled but is not" % (locator)) + self._info("Element '%s' is enabled" % (locator)) + + def element_should_be_disabled(self, locator): + if self._find_element(locator).is_enabled(): + raise AssertionError("Element '%s' should be disabled but is not" % (locator)) + self._info("Element '%s' is disabled" % (locator)) + + def element_value_should_be(self, locator, value): + element = self._find_element(locator) + if str(value) != str(element.get_attribute('value')): + raise AssertionError("Element '%s' value should be '%s' but is '%s'." % + (locator, value, element.get_attribute('value'))) + + def element_text_should_be(self, locator, text): + element = self._find_element(locator) + if element.text != text: + raise AssertionError("Element '%s' text should be '%s' but is '%s'." % + (locator, text, element.text)) + + def _find_element(self, locator): + application = self._current_application() + return self._element_finder.find(application, locator) From e2ca584ba8f477a87ce95e2cf3d839347ae5202e Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 13:04:17 -0300 Subject: [PATCH 3/8] feat: Update readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index fe8803a..2bf792f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # AppiumFlutterLibary + +![PyPI](https://img.shields.io/pypi/v/robotframework-appiumflutterlibrary?color=blue) +![PyPI - Downloads](https://img.shields.io/pypi/dm/robotframework-appiumflutterlibrary) + AppiumFlutterLibrary is a library for testing Flutter apps with [RobotFramework](https://robotframework.org/). + +The project uses the [Flutter Driver](https://flutter.dev/docs/cookbook/testing/integration/introduction) test tools integrated to [Appium](https://appium.io/) as a RobotFramework library. + +## Installation + +Installing using [pip](https://pypi.org/project/robotframework-appiumflutterlibrary/) + +```bash +pip install --upgrade robotframework-appiumflutterlibrary +``` From 09262f4cbd186769caea17b7de79ef8f573460f2 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 13:16:23 -0300 Subject: [PATCH 4/8] feat: upgrade version --- AppiumFlutterLibrary/version.py | 2 +- README.md | 2 +- setup.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/AppiumFlutterLibrary/version.py b/AppiumFlutterLibrary/version.py index a427e8a..bfa6692 100644 --- a/AppiumFlutterLibrary/version.py +++ b/AppiumFlutterLibrary/version.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -VERSION = '1.0.0-alpha.1' \ No newline at end of file +VERSION = '1.0.0-alpha.2' \ No newline at end of file diff --git a/README.md b/README.md index 2bf792f..cbc8416 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The project uses the [Flutter Driver](https://flutter.dev/docs/cookbook/testing/ ## Installation -Installing using [pip](https://pypi.org/project/robotframework-appiumflutterlibrary/) +Install using [pip](https://pypi.org/project/robotframework-appiumflutterlibrary/) ```bash pip install --upgrade robotframework-appiumflutterlibrary diff --git a/setup.py b/setup.py index fd2c850..c6f21af 100644 --- a/setup.py +++ b/setup.py @@ -5,9 +5,8 @@ ROOT = dirname(abspath(__file__)) - setup(name='robotframework-appiumflutterlibrary', - version='1.0.0-alpha.1', + version='1.0.0-alpha.2', description='Robot Framework Mobile flutter app testing library for Appium Client Android & iOS & Web', long_description=open(join(ROOT, 'README.md')).read(), author='Igor Augusto', From d81ee3525a228a18ef876893502809b8231aff4e Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 13:23:31 -0300 Subject: [PATCH 5/8] fix: remove wrong import at element --- AppiumFlutterLibrary/keywords/_element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppiumFlutterLibrary/keywords/_element.py b/AppiumFlutterLibrary/keywords/_element.py index c1a00e0..085b9bc 100644 --- a/AppiumFlutterLibrary/keywords/_element.py +++ b/AppiumFlutterLibrary/keywords/_element.py @@ -1,5 +1,5 @@ from .keywordgroup import KeywordGroup -from AppiumFlutterLibrary.finder import ElementFinder, elementfinder +from AppiumFlutterLibrary.finder import ElementFinder def isstr(s): return isinstance(s, str) From ecf45654d0fa00bdb8b47c9f03fdeaed1a50a051 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 17:52:38 -0300 Subject: [PATCH 6/8] fix: remvoe unfuntional keywords --- .../keywords/_applicationmanagement.py | 2 +- AppiumFlutterLibrary/keywords/_element.py | 25 ++++++------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/AppiumFlutterLibrary/keywords/_applicationmanagement.py b/AppiumFlutterLibrary/keywords/_applicationmanagement.py index eaa1ce5..ff1347c 100644 --- a/AppiumFlutterLibrary/keywords/_applicationmanagement.py +++ b/AppiumFlutterLibrary/keywords/_applicationmanagement.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import robot +import time from AppiumFlutterLibrary.utils import ApplicationCache from AppiumFlutterLibrary.keywords.keywordgroup import KeywordGroup from appium.webdriver import Remote @@ -16,7 +17,6 @@ def close_application(self): def open_application(self, remote_url, alias =None, **kwargs): desired_caps = kwargs application = Remote(str(remote_url), desired_caps) - return self._cache.register(application, alias) def set_appium_timeout(self, seconds): diff --git a/AppiumFlutterLibrary/keywords/_element.py b/AppiumFlutterLibrary/keywords/_element.py index 085b9bc..d59bb23 100644 --- a/AppiumFlutterLibrary/keywords/_element.py +++ b/AppiumFlutterLibrary/keywords/_element.py @@ -1,3 +1,4 @@ +from appium.webdriver.webelement import WebElement from .keywordgroup import KeywordGroup from AppiumFlutterLibrary.finder import ElementFinder @@ -19,24 +20,9 @@ def click_element(self, locator): element.click() def element_should_be_visible(self, locator): - if not self._find_element(locator).is_displayed(): - raise AssertionError("Element '%s' should be visible but not" % locator) - - def element_should_be_enabled(self, locator): - if not self._find_element(locator).is_enabled(): - raise AssertionError("Element '%s' should be enabled but is not" % (locator)) - self._info("Element '%s' is enabled" % (locator)) - - def element_should_be_disabled(self, locator): - if self._find_element(locator).is_enabled(): - raise AssertionError("Element '%s' should be disabled but is not" % (locator)) - self._info("Element '%s' is disabled" % (locator)) - - def element_value_should_be(self, locator, value): element = self._find_element(locator) - if str(value) != str(element.get_attribute('value')): - raise AssertionError("Element '%s' value should be '%s' but is '%s'." % - (locator, value, element.get_attribute('value'))) + if not self._is_visible(element): + raise AssertionError("Element '%s' should be visible but not" % locator) def element_text_should_be(self, locator, text): element = self._find_element(locator) @@ -44,6 +30,11 @@ def element_text_should_be(self, locator, text): raise AssertionError("Element '%s' text should be '%s' but is '%s'." % (locator, text, element.text)) + def _is_visible(self, element): + application = self._current_application() + application.execute_script('flutter:waitFor', element, 1) + return 1 + def _find_element(self, locator): application = self._current_application() return self._element_finder.find(application, locator) From 0fa38beffccb0af4e6a41aed6a23b0369984f0f6 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 18:19:30 -0300 Subject: [PATCH 7/8] feat: raise error when automationName isnt flutter --- AppiumFlutterLibrary/keywords/_applicationmanagement.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AppiumFlutterLibrary/keywords/_applicationmanagement.py b/AppiumFlutterLibrary/keywords/_applicationmanagement.py index ff1347c..88f5992 100644 --- a/AppiumFlutterLibrary/keywords/_applicationmanagement.py +++ b/AppiumFlutterLibrary/keywords/_applicationmanagement.py @@ -16,6 +16,8 @@ def close_application(self): def open_application(self, remote_url, alias =None, **kwargs): desired_caps = kwargs + if desired_caps['automationName'] != 'flutter': + raise ValueError("Appium Flutter Library only suports flutter automation. Try changing automationName capability to 'flutter'") application = Remote(str(remote_url), desired_caps) return self._cache.register(application, alias) From 07ba19e78eb30aca56b0eee20b7dc3b14f3cee90 Mon Sep 17 00:00:00 2001 From: igortavtib Date: Wed, 3 Nov 2021 18:52:15 -0300 Subject: [PATCH 8/8] fix: scroll to element keyword --- AppiumFlutterLibrary/__init__.py | 3 ++- AppiumFlutterLibrary/finder/elementfinder.py | 11 ++++++++++- AppiumFlutterLibrary/keywords/__init__.py | 4 +++- AppiumFlutterLibrary/keywords/_screen.py | 4 ++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/AppiumFlutterLibrary/__init__.py b/AppiumFlutterLibrary/__init__.py index 2bad7cd..425a9fa 100644 --- a/AppiumFlutterLibrary/__init__.py +++ b/AppiumFlutterLibrary/__init__.py @@ -8,9 +8,10 @@ class AppiumFlutterLibrary( _ApplicationManagementKeyWords, _ElementKeywords, + _LoggingKeywords, + _ScreenKeywords, _RunOnFailureKeyWords, _WaintingKeywords, - _LoggingKeywords ): ROBOT_LIBRARY_SCOPE = 'GLOBAL' ROBOT_LIBRARY_VERSION = VERSION diff --git a/AppiumFlutterLibrary/finder/elementfinder.py b/AppiumFlutterLibrary/finder/elementfinder.py index 2f1e78b..5b365e2 100644 --- a/AppiumFlutterLibrary/finder/elementfinder.py +++ b/AppiumFlutterLibrary/finder/elementfinder.py @@ -5,7 +5,8 @@ def __init__(self): self._element_finder = FlutterFinder() self._strategies = { 'xpath': self._find_by_xpath, - 'key': self._find_by_key + 'key': self._find_by_key, + 'text': self._find_by_text, } def find(self, application, locator): @@ -29,6 +30,14 @@ def _find_by_key(self, application, element_key): def _find_by_xpath(self, application, xpath): return + def _find_by_text(self, application, element_text): + finder_text = self._element_finder.by_text(element_text) + element = FlutterElement(application, finder_text) + + return element + + + def _parse_locator(self, locator): prefix = None criteria = locator diff --git a/AppiumFlutterLibrary/keywords/__init__.py b/AppiumFlutterLibrary/keywords/__init__.py index 9a3af9e..7da43b1 100644 --- a/AppiumFlutterLibrary/keywords/__init__.py +++ b/AppiumFlutterLibrary/keywords/__init__.py @@ -1,13 +1,15 @@ from ._applicationmanagement import _ApplicationManagementKeyWords from ._element import _ElementKeywords +from ._logging import _LoggingKeywords from ._runonfailure import _RunOnFailureKeyWords +from ._screen import _ScreenKeywords from ._waiting import _WaintingKeywords -from ._logging import _LoggingKeywords __all__ = [ "_ApplicationManagementKeyWords", "_ElementKeywords", "_LoggingKeywords", "_RunOnFailureKeyWords", + "_ScreenKeywords", "_WaintingKeywords" ] \ No newline at end of file diff --git a/AppiumFlutterLibrary/keywords/_screen.py b/AppiumFlutterLibrary/keywords/_screen.py index 4567861..d2f1cbb 100644 --- a/AppiumFlutterLibrary/keywords/_screen.py +++ b/AppiumFlutterLibrary/keywords/_screen.py @@ -1,4 +1,3 @@ -from _typeshed import ReadableBuffer from AppiumFlutterLibrary.finder import ElementFinder from AppiumFlutterLibrary.keywords.keywordgroup import KeywordGroup @@ -9,4 +8,5 @@ def __init__(self): def scroll_to_element(self, locator): application = self._current_application() element = self._element_finder.find(application, locator) - application.execute_script('flutter:scrollIntoView', element) \ No newline at end of file + self._info(element) + application.execute_script('flutter:scrollIntoView', element, 0) \ No newline at end of file