From 4311ca172338e6ea6c456f210238d7aa9536bf7b Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 13:33:26 +0200 Subject: [PATCH 01/34] Add appium tests --- .gitignore | 15 +++- .gitmodules | 3 + .travis.yml | 9 +++ .travis/run.sh | 4 + .vscode/settings.json | 2 + appium/Gemfile | 10 +++ appium/Gemfile.lock | 150 +++++++++++++++++++++++++++++++++++++ appium/Makefile | 10 +++ appium/conftest.py | 26 +++++++ appium/example | 1 + appium/fastlane/Appfile | 7 ++ appium/fastlane/Fastfile | 65 ++++++++++++++++ appium/fastlane/Pluginfile | 5 ++ appium/requirements.txt | 10 +++ appium/tests/test_ios.py | 37 +++++++++ examples | 1 + 16 files changed, 352 insertions(+), 3 deletions(-) create mode 100644 .travis.yml create mode 100644 .travis/run.sh create mode 100644 appium/Gemfile create mode 100644 appium/Gemfile.lock create mode 100644 appium/Makefile create mode 100644 appium/conftest.py create mode 120000 appium/example create mode 100644 appium/fastlane/Appfile create mode 100644 appium/fastlane/Fastfile create mode 100644 appium/fastlane/Pluginfile create mode 100644 appium/requirements.txt create mode 100644 appium/tests/test_ios.py create mode 160000 examples diff --git a/.gitignore b/.gitignore index dd531e21b1..2ec5b98278 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,15 @@ Carthage/Checkouts **/Pods # Fastlane -fastlane/test_output/ -report.xml -.env +appium/fastlane/test_output/ +appium/fastlane/report.xml +appium/.env +appium/fastlane/README.md + +# Appium + +aws +test_bundle.zip +__pycache__ +.cache +wheelhouse diff --git a/.gitmodules b/.gitmodules index f3471b3d00..7da0204e1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "ios/KSCrash"] path = ios/KSCrash url=https://github.com/kstenerud/KSCrash +[submodule "examples"] + path = examples + url = https://github.com/getsentry/examples diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..712f80c4bc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: objective-c +osx_image: xcode8.3 +cache: +- bundler +- pip +script: +- travis_retry .travis/run.sh +notifications: + email: false diff --git a/.travis/run.sh b/.travis/run.sh new file mode 100644 index 0000000000..cd8ff0b610 --- /dev/null +++ b/.travis/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh +cd appium +bundle install +make test diff --git a/.vscode/settings.json b/.vscode/settings.json index 59b0caf005..faf327b08b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,8 @@ "files.trimTrailingWhitespace": true, "files.ensureSingleFinalNewline": true, + "python.linting.pylintEnabled": false, + "prettier.bracketSpacing": false, "prettier.singleQuote": true, "prettier.printWidth": 90, diff --git a/appium/Gemfile b/appium/Gemfile new file mode 100644 index 0000000000..b734015f82 --- /dev/null +++ b/appium/Gemfile @@ -0,0 +1,10 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +source "https://rubygems.org" + +gem 'fastlane' + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/appium/Gemfile.lock b/appium/Gemfile.lock new file mode 100644 index 0000000000..0dc351d578 --- /dev/null +++ b/appium/Gemfile.lock @@ -0,0 +1,150 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.3.5) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + aws-sdk (2.10.17) + aws-sdk-resources (= 2.10.17) + aws-sdk-core (2.10.17) + aws-sigv4 (~> 1.0) + jmespath (~> 1.0) + aws-sdk-resources (2.10.17) + aws-sdk-core (= 2.10.17) + aws-sigv4 (1.0.1) + babosa (1.0.2) + claide (1.0.2) + colored (1.2) + colored2 (3.1.2) + commander-fastlane (4.4.5) + highline (~> 1.7.2) + declarative (0.0.9) + declarative-option (0.1.0) + domain_name (0.5.20170404) + unf (>= 0.0.5, < 1.0.0) + dotenv (2.2.1) + excon (0.57.1) + faraday (0.12.2) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + faraday_middleware (0.11.0.1) + faraday (>= 0.7.4, < 1.0) + fastimage (2.1.0) + fastlane (2.49.0) + CFPropertyList (>= 2.3, < 3.0.0) + addressable (>= 2.3, < 3.0.0) + babosa (>= 1.0.2, < 2.0.0) + bundler (>= 1.12.0, < 2.0.0) + colored + commander-fastlane (>= 4.4.5, < 5.0.0) + dotenv (>= 2.1.1, < 3.0.0) + excon (>= 0.45.0, < 1.0.0) + faraday (~> 0.9) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.9) + fastimage (>= 2.1.0, < 3.0.0) + gh_inspector (>= 1.0.1, < 2.0.0) + google-api-client (>= 0.12.0, < 0.13.0) + highline (>= 1.7.2, < 2.0.0) + json (< 3.0.0) + mini_magick (~> 4.5.1) + multi_json + multi_xml (~> 0.5) + multipart-post (~> 2.0.0) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 1.1.0, < 2.0.0) + security (= 0.1.3) + slack-notifier (>= 1.3, < 2.0.0) + terminal-notifier (>= 1.6.2, < 2.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + tty-screen (~> 0.5.0) + word_wrap (~> 1.0.0) + xcodeproj (>= 1.4.4, < 2.0.0) + xcpretty (>= 0.2.4, < 1.0.0) + xcpretty-travis-formatter (>= 0.0.3) + fastlane-plugin-aws_device_farm (0.3.0) + aws-sdk + gh_inspector (1.0.3) + google-api-client (0.12.0) + addressable (~> 2.5, >= 2.5.1) + googleauth (~> 0.5) + httpclient (>= 2.8.1, < 3.0) + mime-types (~> 3.0) + representable (~> 3.0) + retriable (>= 2.0, < 4.0) + googleauth (0.5.3) + faraday (~> 0.12) + jwt (~> 1.4) + logging (~> 2.0) + memoist (~> 0.12) + multi_json (~> 1.11) + os (~> 0.9) + signet (~> 0.7) + highline (1.7.8) + http-cookie (1.0.3) + domain_name (~> 0.5) + httpclient (2.8.3) + jmespath (1.3.1) + json (2.1.0) + jwt (1.5.6) + little-plugger (1.1.4) + logging (2.2.2) + little-plugger (~> 1.1) + multi_json (~> 1.10) + memoist (0.16.0) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_magick (4.5.1) + multi_json (1.12.1) + multi_xml (0.6.0) + multipart-post (2.0.0) + nanaimo (0.2.3) + os (0.9.6) + plist (3.3.0) + public_suffix (2.0.5) + representable (3.0.4) + declarative (< 0.1.0) + declarative-option (< 0.2.0) + uber (< 0.2.0) + retriable (3.0.2) + rouge (2.0.7) + rubyzip (1.2.1) + security (0.1.3) + signet (0.7.3) + addressable (~> 2.3) + faraday (~> 0.9) + jwt (~> 1.5) + multi_json (~> 1.10) + slack-notifier (1.5.1) + terminal-notifier (1.8.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + tty-screen (0.5.0) + uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.4) + unicode-display_width (1.3.0) + word_wrap (1.0.0) + xcodeproj (1.5.1) + CFPropertyList (~> 2.3.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.3) + xcpretty (0.2.8) + rouge (~> 2.0.7) + xcpretty-travis-formatter (0.0.4) + xcpretty (~> 0.2, >= 0.0.7) + +PLATFORMS + ruby + +DEPENDENCIES + fastlane + fastlane-plugin-aws_device_farm (>= 0.3.0) + +BUNDLED WITH + 1.15.3 diff --git a/appium/Makefile b/appium/Makefile new file mode 100644 index 0000000000..67e041c78b --- /dev/null +++ b/appium/Makefile @@ -0,0 +1,10 @@ +create-test-bundle: + rm test_bundle.zip | true + zip -r test_bundle.zip tests/ wheelhouse/ requirements.txt conftest.py + +install: + cd example; yarn install + +test: create-test-bundle install + fastlane aws_device_run_ios + fastlane aws_ios_upload_and_run diff --git a/appium/conftest.py b/appium/conftest.py new file mode 100644 index 0000000000..d4e45ff1dc --- /dev/null +++ b/appium/conftest.py @@ -0,0 +1,26 @@ +import os +import pytest + +from appium import webdriver + + +@pytest.fixture(scope='function') +def driver(request): + app = os.path.abspath('/Users/haza/Library/Developer/Xcode/DerivedData/AwesomeProject-gviruxuketsiseechzzeiucbzkzk/Build/Products/Debug-iphonesimulator/AwesomeProject.app') + + screenshot_folder = os.getenv('SCREENSHOT_PATH', '') + + desired_caps = {} + if screenshot_folder == '': + desired_caps['platformName'] = 'iOS' + desired_caps['platformVersion'] = '10.3' + desired_caps['deviceName'] = 'iPhone Simulator' + desired_caps['app'] = app + + _driver = webdriver.Remote( + command_executor='http://127.0.0.1:4723/wd/hub', + desired_capabilities=desired_caps) + + request.addfinalizer(_driver.quit) + + return _driver diff --git a/appium/example b/appium/example new file mode 120000 index 0000000000..425f3b5787 --- /dev/null +++ b/appium/example @@ -0,0 +1 @@ +../examples/react-native/AwesomeProject \ No newline at end of file diff --git a/appium/fastlane/Appfile b/appium/fastlane/Appfile new file mode 100644 index 0000000000..f372081824 --- /dev/null +++ b/appium/fastlane/Appfile @@ -0,0 +1,7 @@ +app_identifier "org.reactjs.native.example.AwesomeProject" # The bundle identifier of your app +apple_id "" # Your Apple email address + +team_id "" # Developer Portal Team ID + +# you can even provide different app identifiers, Apple IDs and team names per lane: +# More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md diff --git a/appium/fastlane/Fastfile b/appium/fastlane/Fastfile new file mode 100644 index 0000000000..30afcb5ef0 --- /dev/null +++ b/appium/fastlane/Fastfile @@ -0,0 +1,65 @@ +fastlane_version "2.48.0" + +default_platform :ios + +platform :ios do + before_all do + # ENV["SLACK_URL"] = "https://hooks.slack.com/services/..." + + end + + desc "Runs all the tests" + lane :test do + scan + end + + lane :aws_device_run_ios do + #update_project_team(path: "example/ios/AwesomeProject.xcodeproj") + + xcodebuild( + scheme: "AwesomeProject", + project: "example/ios/AwesomeProject.xcodeproj", + destination: "generic/platform=iOS", + configuration: "Release", + derivedDataPath: "aws", + xcargs: "GCC_PREPROCESSOR_DEFINITIONS='AWS_UI_TEST' ENABLE_BITCODE=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO build-for-testing" + ) + end + + lane :aws_ios_upload_and_run do + # ENV['AWS_ACCESS_KEY_ID'] = '' + # ENV['AWS_SECRET_ACCESS_KEY'] = '' + ENV['AWS_REGION'] = 'us-west-2' + + # Transform .app into AWS compatible IPA + aws_device_farm_package( + derrived_data_path: "aws", + configuration: "Release" + ) + + # RUN tests on AWS Device Farm + aws_device_farm( + name: "react-native", + test_binary_path: "test_bundle.zip", + test_package_type: "APPIUM_PYTHON_TEST_PACKAGE", + test_type: 'APPIUM_PYTHON' + ) + end + + # You can define as many lanes as you want + + after_all do |lane| + # This block is called, only if the executed lane was successful + + # slack( + # message: "Successfully deployed new App Update." + # ) + end + + error do |lane, exception| + # slack( + # message: exception.message, + # success: false + # ) + end +end diff --git a/appium/fastlane/Pluginfile b/appium/fastlane/Pluginfile new file mode 100644 index 0000000000..f44f37afab --- /dev/null +++ b/appium/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-aws_device_farm', '>= 0.3.0' diff --git a/appium/requirements.txt b/appium/requirements.txt new file mode 100644 index 0000000000..deb6f90c92 --- /dev/null +++ b/appium/requirements.txt @@ -0,0 +1,10 @@ +Appium-Python-Client==0.24 +pbr==3.1.1 +py==1.4.34 +pytest==3.1.3 +selenium==3.4.3 +six==1.10.0 +stevedore==1.24.0 +virtualenv==15.1.0 +virtualenv-clone==0.2.6 +virtualenvwrapper==4.7.2 diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py new file mode 100644 index 0000000000..ffd5cddcf5 --- /dev/null +++ b/appium/tests/test_ios.py @@ -0,0 +1,37 @@ +import os +import json + +from time import sleep + +def test_send_message(driver): + driver.find_element_by_accessibility_id('send message').click() + + sleep(1) + + value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") + event = json.loads(value) + + assert len(event['breadcrumbs']) > 0 + assert len(event['contexts']) > 0 + assert event['message'] == 'TEST message' + assert event['extra']['react'] + assert event['tags']['react'] == '1' + assert len(event['user']) > 0 + #assert value == 'button3' + + # def test_scroll(self): + # els = self.driver.find_elements_by_class_name('XCUIElementTypeButton') + # els[5].click() + + # sleep(1) + # try: + # el = self.driver.find_element_by_accessibility_id('Allow') + # el.click() + # sleep(1) + # except: + # pass + + # el = self.driver.find_element_by_xpath('//XCUIElementTypeMap[1]') + + # location = el.location + # self.driver.swipe(start_x=location['x'], start_y=location['y'], end_x=0.5, end_y=location['y'], duration=800) diff --git a/examples b/examples new file mode 160000 index 0000000000..c637c2bbbd --- /dev/null +++ b/examples @@ -0,0 +1 @@ +Subproject commit c637c2bbbda65525d64661f76968c7e4f39635ab From 15d8e8f1bd8810cdad3caa205e86b7431252f1e1 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 13:36:46 +0200 Subject: [PATCH 02/34] Add file permissions --- .travis/run.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .travis/run.sh diff --git a/.travis/run.sh b/.travis/run.sh old mode 100644 new mode 100755 From 9de84110d257f3ae20499760e1098dc84e5d6b6a Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 13:41:10 +0200 Subject: [PATCH 03/34] Add pip wheel command --- .travis/run.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/run.sh b/.travis/run.sh index cd8ff0b610..9bd92ddc25 100755 --- a/.travis/run.sh +++ b/.travis/run.sh @@ -1,4 +1,5 @@ #!/bin/sh cd appium bundle install +pip wheel --wheel-dir wheelhouse -r requirements.txt make test From 7d22891ece116c9a30b571ef37b0ac64aeccfe7a Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 13:46:48 +0200 Subject: [PATCH 04/34] Add yarn --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 712f80c4bc..c14d2704f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ osx_image: xcode8.3 cache: - bundler - pip +before_install: + - brew update + - brew outdated yarn || brew upgrade yarn script: - travis_retry .travis/run.sh notifications: From a4d69024b90332ea56e7a5ede2ca5ca8987d4fc7 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 13:56:46 +0200 Subject: [PATCH 05/34] Add brew install yarn for travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c14d2704f3..2c757d999b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ cache: - pip before_install: - brew update + - brew install yarn - brew outdated yarn || brew upgrade yarn script: - travis_retry .travis/run.sh From df221c513631078558a3b2fc7a54f8db4cb736f8 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Thu, 27 Jul 2017 15:41:58 +0200 Subject: [PATCH 06/34] Add more tests --- appium/Makefile | 6 +++- appium/conftest.py | 29 +++++++++++++----- appium/fastlane/Fastfile | 18 ++++++----- appium/tests/test_ios.py | 64 +++++++++++++++++++++++++++++++--------- examples | 2 +- 5 files changed, 87 insertions(+), 32 deletions(-) diff --git a/appium/Makefile b/appium/Makefile index 67e041c78b..cdf2f0c076 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -6,5 +6,9 @@ install: cd example; yarn install test: create-test-bundle install - fastlane aws_device_run_ios + fastlane build_for_device_farm fastlane aws_ios_upload_and_run + +local-test: + fastlane build_for_local_appium + pytest -vv tests/ diff --git a/appium/conftest.py b/appium/conftest.py index d4e45ff1dc..58ca66f962 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -6,21 +6,34 @@ @pytest.fixture(scope='function') def driver(request): - app = os.path.abspath('/Users/haza/Library/Developer/Xcode/DerivedData/AwesomeProject-gviruxuketsiseechzzeiucbzkzk/Build/Products/Debug-iphonesimulator/AwesomeProject.app') + return get_driver(request, default_capabilities()) + +@pytest.fixture(scope='function') +def no_reset_driver(request): + desired_caps = default_capabilities() + desired_caps['noReset'] = True + return get_driver(request, desired_caps) + +def get_driver(request, desired_caps): + _driver = webdriver.Remote( + command_executor='http://127.0.0.1:4723/wd/hub', + desired_capabilities=desired_caps) + + request.addfinalizer(_driver.quit) + + return _driver + +def default_capabilities(): + app = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') screenshot_folder = os.getenv('SCREENSHOT_PATH', '') desired_caps = {} + if screenshot_folder == '': desired_caps['platformName'] = 'iOS' desired_caps['platformVersion'] = '10.3' desired_caps['deviceName'] = 'iPhone Simulator' desired_caps['app'] = app - _driver = webdriver.Remote( - command_executor='http://127.0.0.1:4723/wd/hub', - desired_capabilities=desired_caps) - - request.addfinalizer(_driver.quit) - - return _driver + return desired_caps diff --git a/appium/fastlane/Fastfile b/appium/fastlane/Fastfile index 30afcb5ef0..ab564fa40e 100644 --- a/appium/fastlane/Fastfile +++ b/appium/fastlane/Fastfile @@ -8,14 +8,18 @@ platform :ios do end - desc "Runs all the tests" - lane :test do - scan + lane :build_for_local_appium do + xcodebuild( + scheme: "AwesomeProject", + project: "example/ios/AwesomeProject.xcodeproj", + destination: "generic/platform=iOS Simulator", + configuration: "Release", + derivedDataPath: "aws", + xcargs: "GCC_PREPROCESSOR_DEFINITIONS='AWS_UI_TEST' ENABLE_BITCODE=NO CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO build-for-testing" + ) end - lane :aws_device_run_ios do - #update_project_team(path: "example/ios/AwesomeProject.xcodeproj") - + lane :build_for_device_farm do xcodebuild( scheme: "AwesomeProject", project: "example/ios/AwesomeProject.xcodeproj", @@ -46,8 +50,6 @@ platform :ios do ) end - # You can define as many lanes as you want - after_all do |lane| # This block is called, only if the executed lane was successful diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index ffd5cddcf5..38a76f6a05 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -17,21 +17,57 @@ def test_send_message(driver): assert event['extra']['react'] assert event['tags']['react'] == '1' assert len(event['user']) > 0 - #assert value == 'button3' - # def test_scroll(self): - # els = self.driver.find_elements_by_class_name('XCUIElementTypeButton') - # els[5].click() +def test_throw_error(no_reset_driver): - # sleep(1) - # try: - # el = self.driver.find_element_by_accessibility_id('Allow') - # el.click() - # sleep(1) - # except: - # pass + no_reset_driver.find_element_by_accessibility_id('throw error').click() - # el = self.driver.find_element_by_xpath('//XCUIElementTypeMap[1]') + sleep(1) + + no_reset_driver.launch_app() + + sleep(3) + + value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") + + assert value != None + + event = json.loads(value) + + assert len(event['breadcrumbs']) > 0 + assert len(event['contexts']) > 0 + assert event['exception']['values'][0]['value'] == 'Sentry: Test throw error' + assert event['platform'] == 'cocoa' + assert event['level'] == 'fatal' + assert event['dist'] == '1' + assert event['logger'] == 'javascript' + assert event['extra']['react'] + assert event['tags']['react'] == '1' + assert len(event['user']) > 0 + +def test_native_crash(no_reset_driver): - # location = el.location - # self.driver.swipe(start_x=location['x'], start_y=location['y'], end_x=0.5, end_y=location['y'], duration=800) + no_reset_driver.find_element_by_accessibility_id('native crash').click() + + sleep(1) + + no_reset_driver.launch_app() + + sleep(3) + + value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") + + assert value != None + + event = json.loads(value) + + assert len(event['breadcrumbs']) > 0 + assert len(event['contexts']) > 0 + assert len(event['threads']['values']) > 0 + assert len(event['exception']['values']) > 0 + assert len(event['debug_meta']['images']) > 0 + assert event['platform'] == 'cocoa' + assert event['level'] == 'fatal' + assert event['extra']['react'] + assert event['tags']['react'] == '1' + assert len(event['user']) > 0 diff --git a/examples b/examples index c637c2bbbd..2f58cd337f 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit c637c2bbbda65525d64661f76968c7e4f39635ab +Subproject commit 2f58cd337fc71d9562c3b320b9ddc2cc66206e99 From ba652a341966b0adee851d84735ce3f910f15958 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Fri, 28 Jul 2017 08:52:26 +0200 Subject: [PATCH 07/34] Reset app before run --- appium/tests/test_ios.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 38a76f6a05..b8ec4ee389 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -19,19 +19,14 @@ def test_send_message(driver): assert len(event['user']) > 0 def test_throw_error(no_reset_driver): - + no_reset_driver.reset() no_reset_driver.find_element_by_accessibility_id('throw error').click() - sleep(1) - no_reset_driver.launch_app() - sleep(3) - value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") assert value != None - event = json.loads(value) assert len(event['breadcrumbs']) > 0 @@ -46,19 +41,14 @@ def test_throw_error(no_reset_driver): assert len(event['user']) > 0 def test_native_crash(no_reset_driver): - + no_reset_driver.reset() no_reset_driver.find_element_by_accessibility_id('native crash').click() - sleep(1) - no_reset_driver.launch_app() - sleep(3) - value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") assert value != None - event = json.loads(value) assert len(event['breadcrumbs']) > 0 From 94e3fd424d40f661d11ede65ea257a455877523c Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Fri, 28 Jul 2017 09:02:36 +0200 Subject: [PATCH 08/34] Remove travis retry --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c757d999b..457a0cc974 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: objective-c osx_image: xcode8.3 cache: -- bundler -- pip + - bundler + - pip before_install: - brew update - brew install yarn - brew outdated yarn || brew upgrade yarn script: -- travis_retry .travis/run.sh + - .travis/run.sh notifications: email: false From 053bfa79b54a95d405d6401c86dcce3c6065bf32 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Fri, 28 Jul 2017 10:13:47 +0200 Subject: [PATCH 09/34] Remove no reset for devicefarm --- appium/conftest.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/appium/conftest.py b/appium/conftest.py index 58ca66f962..2724889d80 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -11,7 +11,7 @@ def driver(request): @pytest.fixture(scope='function') def no_reset_driver(request): desired_caps = default_capabilities() - desired_caps['noReset'] = True + desired_caps['noReset'] = (runs_on_aws() == True and False or True) return get_driver(request, desired_caps) def get_driver(request, desired_caps): @@ -23,14 +23,15 @@ def get_driver(request, desired_caps): return _driver +def runs_on_aws(): + return os.getenv('SCREENSHOT_PATH', False) != False + def default_capabilities(): app = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') - screenshot_folder = os.getenv('SCREENSHOT_PATH', '') - desired_caps = {} - if screenshot_folder == '': + if runs_on_aws() == False: desired_caps['platformName'] = 'iOS' desired_caps['platformVersion'] = '10.3' desired_caps['deviceName'] = 'iPhone Simulator' From 840d2302e26248779aa4d2af8fac5f075f737ee2 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Fri, 28 Jul 2017 10:44:27 +0200 Subject: [PATCH 10/34] Add on aws fixture to not reset device --- appium/conftest.py | 4 ++++ appium/tests/test_ios.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/appium/conftest.py b/appium/conftest.py index 2724889d80..bedbfbda25 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -23,6 +23,10 @@ def get_driver(request, desired_caps): return _driver +@pytest.fixture(scope='function') +def on_aws(): + return runs_on_aws() + def runs_on_aws(): return os.getenv('SCREENSHOT_PATH', False) != False diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index b8ec4ee389..337d82a0fa 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -6,9 +6,11 @@ def test_send_message(driver): driver.find_element_by_accessibility_id('send message').click() - sleep(1) + sleep(3) value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") + + assert value != None event = json.loads(value) assert len(event['breadcrumbs']) > 0 @@ -18,8 +20,10 @@ def test_send_message(driver): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_throw_error(no_reset_driver): - no_reset_driver.reset() +def test_throw_error(no_reset_driver, on_aws): + if not on_aws: + no_reset_driver.reset() + no_reset_driver.find_element_by_accessibility_id('throw error').click() sleep(1) no_reset_driver.launch_app() @@ -40,8 +44,10 @@ def test_throw_error(no_reset_driver): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_native_crash(no_reset_driver): - no_reset_driver.reset() +def test_native_crash(no_reset_driver, on_aws): + if not on_aws: + no_reset_driver.reset() + no_reset_driver.find_element_by_accessibility_id('native crash').click() sleep(1) no_reset_driver.launch_app() From 6c8a7742abd9afcfe9a275a7037b4b4e0a3a6f11 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Fri, 28 Jul 2017 11:11:10 +0200 Subject: [PATCH 11/34] Add close app before relaunching --- appium/conftest.py | 8 ++------ appium/tests/test_ios.py | 12 ++++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/appium/conftest.py b/appium/conftest.py index bedbfbda25..1bf50cf067 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -11,7 +11,7 @@ def driver(request): @pytest.fixture(scope='function') def no_reset_driver(request): desired_caps = default_capabilities() - desired_caps['noReset'] = (runs_on_aws() == True and False or True) + desired_caps['noReset'] = True return get_driver(request, desired_caps) def get_driver(request, desired_caps): @@ -23,12 +23,8 @@ def get_driver(request, desired_caps): return _driver -@pytest.fixture(scope='function') -def on_aws(): - return runs_on_aws() - def runs_on_aws(): - return os.getenv('SCREENSHOT_PATH', False) != False + return os.getenv('SCREENSHOT_PATH', False) def default_capabilities(): app = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 337d82a0fa..8e72aa4599 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -20,12 +20,12 @@ def test_send_message(driver): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_throw_error(no_reset_driver, on_aws): - if not on_aws: - no_reset_driver.reset() +def test_throw_error(no_reset_driver): + no_reset_driver.reset() no_reset_driver.find_element_by_accessibility_id('throw error').click() sleep(1) + no_reset_driver.close_app() no_reset_driver.launch_app() sleep(3) value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") @@ -44,12 +44,12 @@ def test_throw_error(no_reset_driver, on_aws): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_native_crash(no_reset_driver, on_aws): - if not on_aws: - no_reset_driver.reset() +def test_native_crash(no_reset_driver): + no_reset_driver.reset() no_reset_driver.find_element_by_accessibility_id('native crash').click() sleep(1) + no_reset_driver.close_app() no_reset_driver.launch_app() sleep(3) value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") From cee99c4014a9a16c7e8613c509872a7be2b7f828 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 09:33:32 +0200 Subject: [PATCH 12/34] Show iOS log, Refactor conftest --- appium/conftest.py | 78 +++++++++++++++++++++++++++++++++------- appium/tests/test_ios.py | 24 +++++-------- 2 files changed, 73 insertions(+), 29 deletions(-) diff --git a/appium/conftest.py b/appium/conftest.py index 1bf50cf067..a2ea7d936e 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -1,37 +1,89 @@ import os +import sys import pytest +import traceback from appium import webdriver +DEBUG_DRIVER = os.environ.get('DEBUG_DRIVER') == '1' + + +def hook_driver(driver): + real_execute = driver.command_executor.execute + def execute_proxy(*args, **kwargs): + print 'calling remote', args, kwargs + traceback.print_stack(file=sys.stdout, limit=4) + return real_execute(*args, **kwargs) + driver.command_executor.execute = execute_proxy + + +class DriverProxy(object): + + def __init__(self, make_driver): + self._make_driver = make_driver + self._driver = None + + def quit(self): + if self._driver is None: + return + + # this fails but actually succeeds + try: + self._driver.quit() + except Exception: + pass + self._driver = None + + def relaunch_app(self): + self.quit() + + # this fails but actually succeeds + try: + self.launch_app() + except Exception: + pass + + def _get_driver(self): + if self._driver is None: + self._driver = self._make_driver() + if DEBUG_DRIVER: + hook_driver(self._driver) + return self._driver + + def __getattr__(self, name): + return getattr(self._get_driver(), name) + @pytest.fixture(scope='function') def driver(request): - return get_driver(request, default_capabilities()) + def make_driver(): + return webdriver.Remote( + command_executor='http://127.0.0.1:4723/wd/hub', + desired_capabilities=default_capabilities()) -@pytest.fixture(scope='function') -def no_reset_driver(request): - desired_caps = default_capabilities() - desired_caps['noReset'] = True - return get_driver(request, desired_caps) + driver = DriverProxy(make_driver) + request.addfinalizer(driver.quit) -def get_driver(request, desired_caps): - _driver = webdriver.Remote( - command_executor='http://127.0.0.1:4723/wd/hub', - desired_capabilities=desired_caps) + return driver - request.addfinalizer(_driver.quit) - return _driver +@pytest.fixture(scope='function') +def on_aws(): + return runs_on_aws() + def runs_on_aws(): return os.getenv('SCREENSHOT_PATH', False) + def default_capabilities(): app = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') desired_caps = {} - if runs_on_aws() == False: + desired_caps['noReset'] = True + desired_caps['showIOSLog'] = True + if not runs_on_aws(): desired_caps['platformName'] = 'iOS' desired_caps['platformVersion'] = '10.3' desired_caps['deviceName'] = 'iPhone Simulator' diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 8e72aa4599..7e23de288e 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -20,15 +20,11 @@ def test_send_message(driver): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_throw_error(no_reset_driver): - no_reset_driver.reset() - - no_reset_driver.find_element_by_accessibility_id('throw error').click() - sleep(1) - no_reset_driver.close_app() - no_reset_driver.launch_app() +def test_throw_error(driver): + driver.find_element_by_accessibility_id('throw error').click() + driver.relaunch_app() sleep(3) - value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") + value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") assert value != None event = json.loads(value) @@ -44,15 +40,11 @@ def test_throw_error(no_reset_driver): assert event['tags']['react'] == '1' assert len(event['user']) > 0 -def test_native_crash(no_reset_driver): - no_reset_driver.reset() - - no_reset_driver.find_element_by_accessibility_id('native crash').click() - sleep(1) - no_reset_driver.close_app() - no_reset_driver.launch_app() +def test_native_crash(driver): + driver.find_element_by_accessibility_id('native crash').click() + driver.relaunch_app() sleep(3) - value = no_reset_driver.find_element_by_accessibility_id('textarea').get_attribute("value") + value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") assert value != None event = json.loads(value) From d48758f3820d267bfdaa1620a672ede8bd5fb666 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 26 Jul 2017 14:13:08 +0200 Subject: [PATCH 13/34] Update examples --- examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples b/examples index 2f58cd337f..c5ae7d4f76 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 2f58cd337fc71d9562c3b320b9ddc2cc66206e99 +Subproject commit c5ae7d4f7619bceade90dc4a55724cd22cf7e451 From dbdaa3a70aa2889e4d35663dd3e84d7cbdaaefe6 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 26 Jul 2017 12:52:28 +0200 Subject: [PATCH 14/34] Fix not sending event when native crash happens --- lib/Sentry.js | 5 +++++ lib/raven-plugin.js | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Sentry.js b/lib/Sentry.js index 3f29f90d5c..8352fedfce 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -34,6 +34,7 @@ export class Sentry { event => { Sentry._lastEvent = event; if (Sentry._eventSentSuccessfully) Sentry._eventSentSuccessfully(event); + if (Sentry._internalEventSent) Sentry._internalEventSent(); } ); } @@ -180,4 +181,8 @@ export class Sentry { static _captureEvent(event) { if (Sentry.isNativeClientAvailable()) Sentry._nativeClient.captureEvent(event); } + + static _setInternalEventSent(callback) { + Sentry._internalEventSent = callback; + } } diff --git a/lib/raven-plugin.js b/lib/raven-plugin.js index c084c8a7be..2b5471ed59 100644 --- a/lib/raven-plugin.js +++ b/lib/raven-plugin.js @@ -19,6 +19,7 @@ */ 'use strict'; import {NativeModules} from 'react-native'; +import {Sentry} from './Sentry'; function wrappedCallback(callback) { function dataCallback(data, original) { @@ -135,7 +136,9 @@ function reactNativePlugin(Raven, options, internalDataCallback) { } Raven.captureException(error, captureOptions); // We always want to tunnel errors to the default handler - defaultHandler(error, isFatal); + Sentry._setInternalEventSent(() => { + defaultHandler(error, isFatal); + }); }); } From 44dd086dce179c6983b54f8f945d0b6902f1ad85 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 13:42:32 +0200 Subject: [PATCH 15/34] Fix tests, Add allow_failed_tests --- appium/Makefile | 5 +++-- appium/check_run_failues.rb | 18 ++++++++++++++++++ appium/conftest.py | 2 +- appium/fastlane/Fastfile | 9 ++++++++- appium/fastlane/Pluginfile | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 appium/check_run_failues.rb diff --git a/appium/Makefile b/appium/Makefile index cdf2f0c076..654f3f4dba 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -6,8 +6,9 @@ install: cd example; yarn install test: create-test-bundle install - fastlane build_for_device_farm - fastlane aws_ios_upload_and_run + fastlane build_for_device_farm --verbose + fastlane aws_ios_upload_and_run --verbose + ruby check_run_failues.rb local-test: fastlane build_for_local_appium diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb new file mode 100644 index 0000000000..e8b7da97ad --- /dev/null +++ b/appium/check_run_failues.rb @@ -0,0 +1,18 @@ +require 'aws-sdk' + +arn = File.read('./fastlane/.aws.run.arn') +arn.strip! + +client = ::Aws::DeviceFarm::Client.new + +problems = client.list_unique_problems({ + arn: arn +}) + +problems.unique_problems.each do |up| + raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 + up[1].each do |p| + exception = p.message.match(/crashed: EXC_/) + raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + end +end diff --git a/appium/conftest.py b/appium/conftest.py index a2ea7d936e..5d36213d2d 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -35,7 +35,7 @@ def quit(self): self._driver = None def relaunch_app(self): - self.quit() + #self.quit() if we quit here, we loose connection to the app # this fails but actually succeeds try: diff --git a/appium/fastlane/Fastfile b/appium/fastlane/Fastfile index ab564fa40e..234c16dba4 100644 --- a/appium/fastlane/Fastfile +++ b/appium/fastlane/Fastfile @@ -46,8 +46,15 @@ platform :ios do name: "react-native", test_binary_path: "test_bundle.zip", test_package_type: "APPIUM_PYTHON_TEST_PACKAGE", - test_type: 'APPIUM_PYTHON' + test_type: 'APPIUM_PYTHON', + allow_failed_tests: true ) + + store_run_arn + end + + lane :store_run_arn do + sh("echo #{ENV['AWS_DEVICE_FARM_RUN_ARN']} > .aws.run.arn") end after_all do |lane| diff --git a/appium/fastlane/Pluginfile b/appium/fastlane/Pluginfile index f44f37afab..49dd54635b 100644 --- a/appium/fastlane/Pluginfile +++ b/appium/fastlane/Pluginfile @@ -2,4 +2,4 @@ # # Ensure this file is checked in to source control! -gem 'fastlane-plugin-aws_device_farm', '>= 0.3.0' +gem 'fastlane-plugin-aws_device_farm', :git => 'git://github.com/HazAT/fastlane-plugin-aws_device_farm.git' From f38defa507602b4bd4d0a9a0cdb30d65cd0b5010 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 26 Jul 2017 11:48:42 +0200 Subject: [PATCH 16/34] Fixes #169 - Add check for native client to not persist payload in js --- lib/raven-plugin.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/raven-plugin.js b/lib/raven-plugin.js index 2b5471ed59..39e8e1206b 100644 --- a/lib/raven-plugin.js +++ b/lib/raven-plugin.js @@ -79,15 +79,17 @@ function reactNativePlugin(Raven, options, internalDataCallback) { }) ); - // Check for a previously persisted payload, and report it. - reactNativePlugin._restorePayload().then(function(payload) { - options.onInitialize && options.onInitialize(payload); - if (!payload) return; - Raven._sendProcessedPayload(payload, function(error) { - if (error) return; // Try again next launch. - reactNativePlugin._clearPayload(); - }); - })['catch'](function() {}); + if (options.nativeClientAvailable && options.nativeClientAvailable === false) { + // Check for a previously persisted payload, and report it. + reactNativePlugin._restorePayload().then(function(payload) { + options.onInitialize && options.onInitialize(payload); + if (!payload) return; + Raven._sendProcessedPayload(payload, function(error) { + if (error) return; // Try again next launch. + reactNativePlugin._clearPayload(); + }); + })['catch'](function() {}); + } Raven.setShouldSendCallback(function(data, originalCallback) { if (!(FATAL_ERROR_KEY in data)) { @@ -98,11 +100,13 @@ function reactNativePlugin(Raven, options, internalDataCallback) { var origError = data[FATAL_ERROR_KEY]; delete data[FATAL_ERROR_KEY]; - reactNativePlugin._persistPayload(data).then(function() { - defaultHandler(origError, true); - handlingFatal = false; // In case it isn't configured to crash. - return null; - })['catch'](function() {}); + if (options.nativeClientAvailable && options.nativeClientAvailable === false) { + reactNativePlugin._persistPayload(data).then(function() { + defaultHandler(origError, true); + handlingFatal = false; // In case it isn't configured to crash. + return null; + })['catch'](function() {}); + } return false; // Do not continue. }); From c5f9c35488b7429d20025fe4890d2c451a11494b Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 15:27:08 +0200 Subject: [PATCH 17/34] Add callback after successfully send event to native integration --- .../java/io/sentry/RNSentryEventEmitter.java | 2 ++ .../main/java/io/sentry/RNSentryModule.java | 1 + appium/check_run_failues.rb | 7 ++-- ios/RNSentry.m | 1 + ios/RNSentryEventEmitter.h | 2 +- ios/RNSentryEventEmitter.m | 14 +++++--- lib/Sentry.js | 8 +++-- lib/raven-plugin.js | 32 +++++++++---------- 8 files changed, 39 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/io/sentry/RNSentryEventEmitter.java b/android/src/main/java/io/sentry/RNSentryEventEmitter.java index 7604dd8fc0..d03c324409 100644 --- a/android/src/main/java/io/sentry/RNSentryEventEmitter.java +++ b/android/src/main/java/io/sentry/RNSentryEventEmitter.java @@ -11,6 +11,7 @@ public class RNSentryEventEmitter extends ReactContextBaseJavaModule { public static final String SENTRY_EVENT_SENT_SUCCESSFULLY = "Sentry/eventSentSuccessfully"; + public static final String SENTRY_EVENT_STORED = "Sentry/eventStored"; public RNSentryEventEmitter(ReactApplicationContext reactContext) { super(reactContext); @@ -25,6 +26,7 @@ public String getName() { public Map getConstants() { final Map constants = new HashMap<>(); constants.put("EVENT_SENT_SUCCESSFULLY", SENTRY_EVENT_SENT_SUCCESSFULLY); + constants.put("EVENT_STORED", SENTRY_EVENT_STORED); return constants; } diff --git a/android/src/main/java/io/sentry/RNSentryModule.java b/android/src/main/java/io/sentry/RNSentryModule.java index cac91226bd..c4d6000cf4 100644 --- a/android/src/main/java/io/sentry/RNSentryModule.java +++ b/android/src/main/java/io/sentry/RNSentryModule.java @@ -231,6 +231,7 @@ public void captureEvent(ReadableMap event) { } Sentry.capture(buildEvent(eventBuilder)); + RNSentryEventEmitter.sendEvent(reactContext, RNSentryEventEmitter.SENTRY_EVENT_STORED, new WritableNativeMap()); } @ReactMethod diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index e8b7da97ad..31444f0582 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -12,7 +12,10 @@ problems.unique_problems.each do |up| raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 up[1].each do |p| - exception = p.message.match(/crashed: EXC_/) - raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + if p.problems[0].test.name == 'test_native_crash' || + p.problems[0].test.name == 'test_throw_error' + exception = p.message.match(/crashed: EXC_/) + raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + end end end diff --git a/ios/RNSentry.m b/ios/RNSentry.m index 696c5708b1..184e9a0e80 100644 --- a/ios/RNSentry.m +++ b/ios/RNSentry.m @@ -355,6 +355,7 @@ - (void)swizzleCallNativeModule:(Class)class { [self addExceptionToEvent:sentryEvent type:exception[@"type"] value:exception[@"value"] frames:frames]; } [SentryClient.sharedClient sendEvent:sentryEvent withCompletionHandler:NULL]; + [RNSentryEventEmitter emitStoredEvent]; } - (void)addExceptionToEvent:(SentryEvent *)event type:(NSString *)type value:(NSString *)value frames:(NSArray *)frames { diff --git a/ios/RNSentryEventEmitter.h b/ios/RNSentryEventEmitter.h index 292be816c7..9d2db914ed 100644 --- a/ios/RNSentryEventEmitter.h +++ b/ios/RNSentryEventEmitter.h @@ -11,6 +11,6 @@ @interface RNSentryEventEmitter : RCTEventEmitter -+ (void)successfullySentEventWithId:(NSString *)eventId; ++ (void)emitStoredEvent; @end diff --git a/ios/RNSentryEventEmitter.m b/ios/RNSentryEventEmitter.m index b96613665e..f94a4cb546 100644 --- a/ios/RNSentryEventEmitter.m +++ b/ios/RNSentryEventEmitter.m @@ -9,17 +9,21 @@ #import "RNSentryEventEmitter.h" NSString *const kEventSentSuccessfully = @"Sentry/eventSentSuccessfully"; +NSString *const kEventStored = @"Sentry/eventStored"; @implementation RNSentryEventEmitter RCT_EXPORT_MODULE(); - (NSDictionary *)constantsToExport { - return @{ @"EVENT_SENT_SUCCESSFULLY": kEventSentSuccessfully}; + return @{ + @"EVENT_SENT_SUCCESSFULLY": kEventSentSuccessfully, + @"EVENT_STORED": kEventStored + }; } - (NSArray *)supportedEvents { - return @[@"Sentry/eventSentSuccessfully"]; + return @[kEventSentSuccessfully, kEventStored]; } @@ -36,13 +40,13 @@ - (void)stopObserving { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -+ (void)successfullySentEventWithId:(NSString *)eventId { - [self postNotificationName:kEventSentSuccessfully withPayload:eventId]; ++ (void)emitStoredEvent { + [self postNotificationName:kEventStored withPayload:@""]; } + (void)postNotificationName:(NSString *)name withPayload:(NSObject *)object { NSDictionary *payload = @{@"payload": object}; - + [[NSNotificationCenter defaultCenter] postNotificationName:name object:self userInfo:payload]; diff --git a/lib/Sentry.js b/lib/Sentry.js index 8352fedfce..de8e5d4816 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -34,9 +34,11 @@ export class Sentry { event => { Sentry._lastEvent = event; if (Sentry._eventSentSuccessfully) Sentry._eventSentSuccessfully(event); - if (Sentry._internalEventSent) Sentry._internalEventSent(); } ); + Sentry.eventEmitter.addListener(RNSentryEventEmitter.EVENT_STORED, () => { + if (Sentry._internalEventStored) Sentry._internalEventStored(); + }); } Sentry._ravenClient = new RavenClient(Sentry._dsn, Sentry.options); } @@ -182,7 +184,7 @@ export class Sentry { if (Sentry.isNativeClientAvailable()) Sentry._nativeClient.captureEvent(event); } - static _setInternalEventSent(callback) { - Sentry._internalEventSent = callback; + static _setInternalEventStored(callback) { + Sentry._internalEventStored = callback; } } diff --git a/lib/raven-plugin.js b/lib/raven-plugin.js index 39e8e1206b..96df55caac 100644 --- a/lib/raven-plugin.js +++ b/lib/raven-plugin.js @@ -65,10 +65,6 @@ function urlencode(obj) { function reactNativePlugin(Raven, options, internalDataCallback) { options = options || {}; - // react-native doesn't have a document, so can't use default Image - // transport - use XMLHttpRequest instead - Raven.setTransport(reactNativePlugin._transport); - // Use data callback to strip device-specific paths from stack traces Raven.setDataCallback( wrappedCallback(function(data) { @@ -80,6 +76,10 @@ function reactNativePlugin(Raven, options, internalDataCallback) { ); if (options.nativeClientAvailable && options.nativeClientAvailable === false) { + // react-native doesn't have a document, so can't use default Image + // transport - use XMLHttpRequest instead + Raven.setTransport(reactNativePlugin._transport); + // Check for a previously persisted payload, and report it. reactNativePlugin._restorePayload().then(function(payload) { options.onInitialize && options.onInitialize(payload); @@ -89,27 +89,25 @@ function reactNativePlugin(Raven, options, internalDataCallback) { reactNativePlugin._clearPayload(); }); })['catch'](function() {}); - } - Raven.setShouldSendCallback(function(data, originalCallback) { - if (!(FATAL_ERROR_KEY in data)) { - // not a fatal (will not crash runtime), continue as planned - return originalCallback ? originalCallback.call(this, data) : true; - } + Raven.setShouldSendCallback(function(data, originalCallback) { + if (!(FATAL_ERROR_KEY in data)) { + // not a fatal (will not crash runtime), continue as planned + return originalCallback ? originalCallback.call(this, data) : true; + } - var origError = data[FATAL_ERROR_KEY]; - delete data[FATAL_ERROR_KEY]; + var origError = data[FATAL_ERROR_KEY]; + delete data[FATAL_ERROR_KEY]; - if (options.nativeClientAvailable && options.nativeClientAvailable === false) { reactNativePlugin._persistPayload(data).then(function() { defaultHandler(origError, true); handlingFatal = false; // In case it isn't configured to crash. return null; })['catch'](function() {}); - } - return false; // Do not continue. - }); + return false; // Do not continue. + }); + } // Make sure that if multiple fatals occur, we only persist the first one. // @@ -140,7 +138,7 @@ function reactNativePlugin(Raven, options, internalDataCallback) { } Raven.captureException(error, captureOptions); // We always want to tunnel errors to the default handler - Sentry._setInternalEventSent(() => { + Sentry._setInternalEventStored(() => { defaultHandler(error, isFatal); }); }); From 1eb00e1cc83610483d960f62ba04dc10d478157b Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 15:31:55 +0200 Subject: [PATCH 18/34] Add copy local files to example --- appium/Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/appium/Makefile b/appium/Makefile index 654f3f4dba..53609c3ea0 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -5,7 +5,15 @@ create-test-bundle: install: cd example; yarn install -test: create-test-bundle install +copy-local-files-to-example: + rm -rf example/node_modules/react-native-sentry/lib/* + rm -rf example/node_modules/react-native-sentry/ios/* + rm -rf example/node_modules/react-native-sentry/android/* + cp -r ../lib/* example/node_modules/react-native-sentry/lib/ + cp -r ../ios/* example/node_modules/react-native-sentry/ios/ + cp -r ../android/* example/node_modules/react-native-sentry/android/ + +test: create-test-bundle install copy-local-files-to-example fastlane build_for_device_farm --verbose fastlane aws_ios_upload_and_run --verbose ruby check_run_failues.rb From ebeea9b87c198344e1471c5032b6b94a8ce44294 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 16:08:07 +0200 Subject: [PATCH 19/34] Remove verbose fastlane step --- appium/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appium/Makefile b/appium/Makefile index 53609c3ea0..e5565673c1 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -14,8 +14,8 @@ copy-local-files-to-example: cp -r ../android/* example/node_modules/react-native-sentry/android/ test: create-test-bundle install copy-local-files-to-example - fastlane build_for_device_farm --verbose - fastlane aws_ios_upload_and_run --verbose + fastlane build_for_device_farm + fastlane aws_ios_upload_and_run ruby check_run_failues.rb local-test: From d5c6cc147882750e79c130f0d010be5e8bc98a2c Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Mon, 31 Jul 2017 16:43:14 +0200 Subject: [PATCH 20/34] Update copy command --- appium/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appium/Makefile b/appium/Makefile index e5565673c1..4ef8f9ecc2 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -7,10 +7,10 @@ install: copy-local-files-to-example: rm -rf example/node_modules/react-native-sentry/lib/* - rm -rf example/node_modules/react-native-sentry/ios/* + find example/node_modules/react-native-sentry/ios -name 'RN*.[h|m]' -exec rm {} \; rm -rf example/node_modules/react-native-sentry/android/* cp -r ../lib/* example/node_modules/react-native-sentry/lib/ - cp -r ../ios/* example/node_modules/react-native-sentry/ios/ + find ../ios -name 'RN*.[h|m]' -exec cp {} example/node_modules/react-native-sentry/ios/ \; cp -r ../android/* example/node_modules/react-native-sentry/android/ test: create-test-bundle install copy-local-files-to-example From 168213475669ba6146218de1a177b5704b58933f Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 00:53:02 +0200 Subject: [PATCH 21/34] Download syslog and see if error got sent --- appium/check_run_failues.rb | 20 ++++++++++++++++++-- examples | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index 31444f0582..57772bb59b 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -1,4 +1,5 @@ require 'aws-sdk' +require 'open-uri' arn = File.read('./fastlane/.aws.run.arn') arn.strip! @@ -12,10 +13,25 @@ problems.unique_problems.each do |up| raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 up[1].each do |p| - if p.problems[0].test.name == 'test_native_crash' || - p.problems[0].test.name == 'test_throw_error' + + if p.problems[0].test.name == 'test_throw_error' + artifacts = client.list_artifacts({ + type: "FILE", + arn: p.problems[0].test.arn + }) + artifacts.artifacts.each do |a| + if a.name == 'Syslog' + content = open(a.url).read + exception = content.match(/Sentry - Verbose:: Sending JSON/) + raise RuntimeError, "No JSON SENT: #{p.inspect}" unless !exception.nil? + exception = nil + end + end + end + if p.problems[0].test.name == 'test_native_crash' exception = p.message.match(/crashed: EXC_/) raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + exception = nil end end end diff --git a/examples b/examples index c5ae7d4f76..ff5edb45ee 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit c5ae7d4f7619bceade90dc4a55724cd22cf7e451 +Subproject commit ff5edb45ee5b794d22a72687f8e31dcdac6d54bd From 7d7e6633256d736c95d66e4e37b123d3ad28ea80 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 11:49:27 +0200 Subject: [PATCH 22/34] Improve native crash test, Update sentry-cocoa to 3.3.0 --- appium/Makefile | 2 ++ appium/tests/test_ios.py | 42 ++++++++++++++++++++++++++-------------- ios/Sentry | 2 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/appium/Makefile b/appium/Makefile index 4ef8f9ecc2..e987400016 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -8,10 +8,12 @@ install: copy-local-files-to-example: rm -rf example/node_modules/react-native-sentry/lib/* find example/node_modules/react-native-sentry/ios -name 'RN*.[h|m]' -exec rm {} \; + rm -rf example/node_modules/react-native-sentry/ios/Sentry/Sources/Sentry/* rm -rf example/node_modules/react-native-sentry/android/* cp -r ../lib/* example/node_modules/react-native-sentry/lib/ find ../ios -name 'RN*.[h|m]' -exec cp {} example/node_modules/react-native-sentry/ios/ \; cp -r ../android/* example/node_modules/react-native-sentry/android/ + cp -r ../ios/Sentry/Sources/Sentry/* example/node_modules/react-native-sentry/ios/Sentry/Sources/Sentry/ test: create-test-bundle install copy-local-files-to-example fastlane build_for_device_farm diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 7e23de288e..4bbaf40457 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -23,35 +23,47 @@ def test_send_message(driver): def test_throw_error(driver): driver.find_element_by_accessibility_id('throw error').click() driver.relaunch_app() - sleep(3) value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") + # the crash should have been already sent + assert value is None + # event = json.loads(value) - assert value != None - event = json.loads(value) - - assert len(event['breadcrumbs']) > 0 - assert len(event['contexts']) > 0 - assert event['exception']['values'][0]['value'] == 'Sentry: Test throw error' - assert event['platform'] == 'cocoa' - assert event['level'] == 'fatal' - assert event['dist'] == '1' - assert event['logger'] == 'javascript' - assert event['extra']['react'] - assert event['tags']['react'] == '1' - assert len(event['user']) > 0 + # assert len(event['breadcrumbs']) > 0 + # assert len(event['contexts']) > 0 + # assert event['exception']['values'][0]['value'] == 'Sentry: Test throw error' + # assert event['platform'] == 'cocoa' + # assert event['level'] == 'fatal' + # assert event['dist'] == '1' + # assert event['logger'] == 'javascript' + # assert event['extra']['react'] + # assert event['tags']['react'] == '1' + # assert len(event['user']) > 0 def test_native_crash(driver): + sleep(2) driver.find_element_by_accessibility_id('native crash').click() driver.relaunch_app() sleep(3) value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") - + # the crash should have been already sent assert value != None event = json.loads(value) assert len(event['breadcrumbs']) > 0 assert len(event['contexts']) > 0 assert len(event['threads']['values']) > 0 + for thread in event['threads']['values']: + if thread['crashed']: + assert len(thread['stacktrace']['frames']) > 0 + cocoa_frames = 0 + js_frames = 0 + for frame in thread['stacktrace']['frames']: + if frame.get('package', None): + cocoa_frames += 1 + if frame.get('platform', None) == 'javascript': + js_frames += 1 + assert cocoa_frames > 0 + assert js_frames > 0 # does not work in release build assert len(event['exception']['values']) > 0 assert len(event['debug_meta']['images']) > 0 assert event['platform'] == 'cocoa' diff --git a/ios/Sentry b/ios/Sentry index 8387778705..67a34cdf01 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit 8387778705edb289156993c2beb2098e719ff449 +Subproject commit 67a34cdf01c006e8f0d70568e0c9268931f93788 From 0df7dfb249f3c39884c82e7813be3913937429be Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 12:49:48 +0200 Subject: [PATCH 23/34] Update sentry-cocoa to 3.3.1 --- appium/check_run_failues.rb | 4 ++-- ios/Sentry | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index 57772bb59b..6c7550f87f 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -22,8 +22,8 @@ artifacts.artifacts.each do |a| if a.name == 'Syslog' content = open(a.url).read - exception = content.match(/Sentry - Verbose:: Sending JSON/) - raise RuntimeError, "No JSON SENT: #{p.inspect}" unless !exception.nil? + exception = content.scan(/Sentry - Verbose:: Sending JSON/).size + raise RuntimeError, "No JSON SENT: #{p.inspect}" unless exception == 1 exception = nil end end diff --git a/ios/Sentry b/ios/Sentry index 67a34cdf01..35dcbb4923 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit 67a34cdf01c006e8f0d70568e0c9268931f93788 +Subproject commit 35dcbb4923e85fa9d97a8b88d5bb575f04a09070 From d5d8831de7e6da9a885ac1c50692531f7a451c94 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 13:16:47 +0200 Subject: [PATCH 24/34] Bump sentry-cocoa to 3.3.2 --- appium/check_run_failues.rb | 6 +++--- appium/tests/test_ios.py | 2 ++ ios/Sentry | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index 6c7550f87f..d9592f2e36 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -22,9 +22,9 @@ artifacts.artifacts.each do |a| if a.name == 'Syslog' content = open(a.url).read - exception = content.scan(/Sentry - Verbose:: Sending JSON/).size - raise RuntimeError, "No JSON SENT: #{p.inspect}" unless exception == 1 - exception = nil + raise RuntimeError, "No JSON SENT: #{p.inspect}" unless content.scan(/Sentry - Verbose:: Sending JSON/).size == 1 + raise RuntimeError, "Wrong exception value: #{p.inspect}" unless content.scan(/"value" : "Sentry: Test throw error"/).size == 1 + raise RuntimeError, "No javascript frames: #{p.inspect}" unless content.scan(/"platform" : "javascript"/).size >= 1 end end end diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 4bbaf40457..e70aeaf3ec 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -18,6 +18,8 @@ def test_send_message(driver): assert event['message'] == 'TEST message' assert event['extra']['react'] assert event['tags']['react'] == '1' + assert event['sdk'] == False + assert event['sdk']['integrations'][0] == 'react-native' assert len(event['user']) > 0 def test_throw_error(driver): diff --git a/ios/Sentry b/ios/Sentry index 35dcbb4923..6065445322 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit 35dcbb4923e85fa9d97a8b88d5bb575f04a09070 +Subproject commit 6065445322edd5cb3024d9a8b0e4995feeffb8ab From 42a0ac1dd8ef70c7ce85bb38309ac2e066da727f Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 15:31:37 +0200 Subject: [PATCH 25/34] Prepare android tests --- .travis.yml | 4 ++ .travis/run.sh | 9 +++- appium/Makefile | 17 ++++++- appium/check_run_failues.rb | 77 ++++++++++++++++++++++--------- appium/conftest.py | 16 ++++--- appium/fastlane/Fastfile | 21 ++++++++- appium/fastlane/release.keystore | Bin 0 -> 2246 bytes appium/tests/test_android.py | 37 +++++++++++++++ appium/tests/test_ios.py | 12 ----- 9 files changed, 150 insertions(+), 43 deletions(-) create mode 100644 appium/fastlane/release.keystore create mode 100644 appium/tests/test_android.py diff --git a/.travis.yml b/.travis.yml index 457a0cc974..1dfa91f29c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,5 +9,9 @@ before_install: - brew outdated yarn || brew upgrade yarn script: - .travis/run.sh +env: + matrix: + - LANE=ios + - LANE=android notifications: email: false diff --git a/.travis/run.sh b/.travis/run.sh index 9bd92ddc25..e61c5b11f8 100755 --- a/.travis/run.sh +++ b/.travis/run.sh @@ -2,4 +2,11 @@ cd appium bundle install pip wheel --wheel-dir wheelhouse -r requirements.txt -make test + +if [ "$LANE" = "ios" ]; +then + make test +else + make test-android +fi +fastlane $LANE diff --git a/appium/Makefile b/appium/Makefile index e987400016..cc224c2f20 100644 --- a/appium/Makefile +++ b/appium/Makefile @@ -1,6 +1,10 @@ create-test-bundle: rm test_bundle.zip | true - zip -r test_bundle.zip tests/ wheelhouse/ requirements.txt conftest.py + zip -r test_bundle.zip tests/test_ios.py wheelhouse/ requirements.txt conftest.py + +create-android-test-bundle: + rm test_bundle.zip | true + zip -r test_bundle.zip tests/test_android.py wheelhouse/ requirements.txt conftest.py install: cd example; yarn install @@ -20,6 +24,15 @@ test: create-test-bundle install copy-local-files-to-example fastlane aws_ios_upload_and_run ruby check_run_failues.rb +test-android: create-android-test-bundle install copy-local-files-to-example + fastlane build_android_for_device_farm + fastlane aws_android_upload_and_run + ANDROID=1 ruby check_run_failues.rb + +local-android-test: + fastlane build_android_for_device_farm + ANDROID=1 pytest -vv tests/test_android.py + local-test: fastlane build_for_local_appium - pytest -vv tests/ + pytest -vv tests/test_ios.py diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index d9592f2e36..a69a4c7e76 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -4,34 +4,69 @@ arn = File.read('./fastlane/.aws.run.arn') arn.strip! -client = ::Aws::DeviceFarm::Client.new +@client = ::Aws::DeviceFarm::Client.new -problems = client.list_unique_problems({ +@problems = @client.list_unique_problems({ arn: arn }) -problems.unique_problems.each do |up| - raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 - up[1].each do |p| - - if p.problems[0].test.name == 'test_throw_error' - artifacts = client.list_artifacts({ - type: "FILE", - arn: p.problems[0].test.arn - }) - artifacts.artifacts.each do |a| - if a.name == 'Syslog' - content = open(a.url).read - raise RuntimeError, "No JSON SENT: #{p.inspect}" unless content.scan(/Sentry - Verbose:: Sending JSON/).size == 1 - raise RuntimeError, "Wrong exception value: #{p.inspect}" unless content.scan(/"value" : "Sentry: Test throw error"/).size == 1 - raise RuntimeError, "No javascript frames: #{p.inspect}" unless content.scan(/"platform" : "javascript"/).size >= 1 + +def android_check + @problems.unique_problems.each do |up| + raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 + up[1].each do |p| + if p.problems[0].test.name == 'test_throw_error' + artifacts = @client.list_artifacts({ + type: "FILE", + arn: p.problems[0].test.arn + }) + puts artifacts.inspect + artifacts.artifacts.each do |a| + if a.name == 'Logcat' + content = open(a.url).read + raise RuntimeError, "Missing value raven: #{p.inspect}" unless content.scan(/"Raven about to send:', {"/).size == 1 + end end end + # if p.problems[0].test.name == 'test_native_crash' + # exception = p.message.match(/crashed: EXC_/) + # raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + # exception = nil + # end end - if p.problems[0].test.name == 'test_native_crash' - exception = p.message.match(/crashed: EXC_/) - raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? - exception = nil + end +end + +def ios_check + @problems.unique_problems.each do |up| + raise RuntimeError, "No failed tests: #{up.inspect}" unless up.length == 2 + up[1].each do |p| + if p.problems[0].test.name == 'test_throw_error' + artifacts = @client.list_artifacts({ + type: "FILE", + arn: p.problems[0].test.arn + }) + artifacts.artifacts.each do |a| + if a.name == 'Syslog' + content = open(a.url).read + raise RuntimeError, "No JSON SENT: #{p.inspect}" unless content.scan(/Sentry - Verbose:: Sending JSON/).size == 1 + raise RuntimeError, "Wrong exception value: #{p.inspect}" unless content.scan(/"value" : "Sentry: Test throw error"/).size == 1 + raise RuntimeError, "No javascript frames: #{p.inspect}" unless content.scan(/"platform" : "javascript"/).size >= 1 + end + end + end + if p.problems[0].test.name == 'test_native_crash' + exception = p.message.match(/crashed: EXC_/) + raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? + exception = nil + end end end end + + +if ENV['ANDROID'] == '1' + android_check +else + ios_check +end diff --git a/appium/conftest.py b/appium/conftest.py index 5d36213d2d..3600ae7f9a 100644 --- a/appium/conftest.py +++ b/appium/conftest.py @@ -77,16 +77,20 @@ def runs_on_aws(): def default_capabilities(): - app = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') - desired_caps = {} desired_caps['noReset'] = True desired_caps['showIOSLog'] = True if not runs_on_aws(): - desired_caps['platformName'] = 'iOS' - desired_caps['platformVersion'] = '10.3' - desired_caps['deviceName'] = 'iPhone Simulator' - desired_caps['app'] = app + if os.environ.get('ANDROID') == '1': + desired_caps['app'] = os.path.abspath('example/android/app/build/outputs/apk/app-release-unsigned.apk') + desired_caps['platformName'] = 'Android' + desired_caps['deviceName'] = 'Android' + else: + desired_caps['app'] = os.path.abspath('aws/Build/Products/Release-iphonesimulator/AwesomeProject.app') + desired_caps['platformName'] = 'iOS' + desired_caps['platformVersion'] = '10.3' + desired_caps['deviceName'] = 'iPhone Simulator' + return desired_caps diff --git a/appium/fastlane/Fastfile b/appium/fastlane/Fastfile index 234c16dba4..92f9e5dabc 100644 --- a/appium/fastlane/Fastfile +++ b/appium/fastlane/Fastfile @@ -33,7 +33,7 @@ platform :ios do lane :aws_ios_upload_and_run do # ENV['AWS_ACCESS_KEY_ID'] = '' # ENV['AWS_SECRET_ACCESS_KEY'] = '' - ENV['AWS_REGION'] = 'us-west-2' + # ENV['AWS_REGION'] = 'us-west-2' # Transform .app into AWS compatible IPA aws_device_farm_package( @@ -53,6 +53,25 @@ platform :ios do store_run_arn end + lane :build_android_for_device_farm do + sh("cd ../example/android/; ./gradlew assembleRelease --stacktrace") + sh("jarsigner -verbose -digestalg SHA1 -sigalg MD5withRSA -keystore release.keystore -storepass 123456 ../example/android/app/build/outputs/apk/app-release-unsigned.apk release") + end + + lane :aws_android_upload_and_run do + aws_device_farm( + name: "react-native", + binary_path: "example/android/app/build/outputs/apk/app-release-unsigned.apk", + device_pool: "Android", + test_binary_path: "test_bundle.zip", + test_package_type: "APPIUM_PYTHON_TEST_PACKAGE", + test_type: 'APPIUM_PYTHON', + allow_failed_tests: true + ) + + store_run_arn + end + lane :store_run_arn do sh("echo #{ENV['AWS_DEVICE_FARM_RUN_ARN']} > .aws.run.arn") end diff --git a/appium/fastlane/release.keystore b/appium/fastlane/release.keystore new file mode 100644 index 0000000000000000000000000000000000000000..e7dd22b21910af5721dd2bcb08f5979e05390c63 GIT binary patch literal 2246 zcmchYc{J1uAI9f5GxmKa%UCYO7=~f&q-e;##wb%XwltO^yNt08(%7>^me9=-x>9K* z6@^OCSTeSl5z3NX*SY6?-*eCD|M!pQkLUB(_dMr0&-Y;IUVsPN-4o60SGtiM!b(U^+|Ot+a`yM$U* zM6)cn_BY^GpIHgdU~L)ca|pY-(rZq@T&5(wjpGwU+nhfu(Iv7L5yG@d3n}BSu9GJv z*oY4oS*nQaU@wg9Np;o=SW^9nl=u;LwylVYI zzj;4py_?CFt|{giP31D1cpTop)K^srmk8rDdKK;{@U3}tbk$*dGHQg+Bi|#{bL?w_ zLm*YZ(n8;P+lWnT7t~-k?pXYC#ara* z7;nD~cULG&#fQQ_C|47k;XUx@^ab9*?)fLh3mr6OlV}twi;{rY>ySgiCKhQlYI&T{ zOT~!W_$4eRsmU?-UD}^RehHNu)nxEuHBB7(#o~)WK+8{tLUbwqoZMI zl8#7hn`!^fX;iFg?z%2fA!8$|^qpA{N}3Di2~0MNX6KS3^yZB7+iHV{z7T0o#-4YZ z(PE-Ej*wIeO)V6H42g z*U6yCYbNd|PMu(Y^E+wl4MvgJ7hKq*+AZFH@T%R0<2b&An1C@__A6eJZk59LP zvqe`3C&qUGIuP5X(dD}B&ys%aSr6m5Kwws*68&W81oe5{k90*jJHuOWFQ440yvScS z!w^3&-C5vZceM1z44fwI3G&bFchg70*E-6`*iqVjxA1;Rc?A`bjfzu?m}<7jp5se? z6n9G6QLjI&a+ECe!s)91xxKeqpF%?E=I~h?UvCn%FyF*U69*{wz4sXCijT9e+&C96 zPnHdnHP8`{Su1KH22_y91nK{cE!)ensm7Ie7?{X%~o3i&9_Y~Z+I)nxcx zC{yfIxoaIFhCYM9T*xm}HQ6|tX4sH9QX5dSCpK5YeE=#0MoGH94J$cK#w{qGQmU4- z(riX$ok1@apRRlNo=Eb}<>`m+YAPX14c*L!Y_3k4~t> zzG12y;$HxuFlWffv`AzUH^T_gOL zu>VHbej}W}5w70|B zAVh!#*mP+LtrR|6sCJ z{s}GQ+s__T40u`kkn`@KV@(CjT|XNZSIa#t5aCl$QD;Ka?xzpSi6%KuLM+2h)tiN2~D?HX~RDQ74n`+d$yuf|m zp+pV`vm0Pn215W4P$`FmA*Bx+BFzgGg$iFRU&~>N`*Nx(wxMJTN*v>LI8FW?;$f!_ zLj*vP(YpC5Ik@BLlwI_&uG$7q&<9DYZ#d+}GQ^=R^Yue*1(Uc|aNnob!&+%o?Z)&s zww=*A(3+6|Z3g0vubq}qWLx`ZgUer@&82NJQ-XcSK38s>uG=!Z+?G@<1J7EX0PWe` z$kR`!ff#UPvFX9|^ajOhkq@}~M0Bm>OK z3<{zT@{Xv6U4psA)rX^A$m(exIK$(7ol;ZbgGmg&vu8Xbn|DT2#7aKB%8N3JVVC_( XFw@7C_ML2MaJFU4`<*Ocv@rh$?D62( literal 0 HcmV?d00001 diff --git a/appium/tests/test_android.py b/appium/tests/test_android.py new file mode 100644 index 0000000000..1782e241cb --- /dev/null +++ b/appium/tests/test_android.py @@ -0,0 +1,37 @@ +import os +import json + +from time import sleep + +def test_send_message(driver): + driver.find_element_by_accessibility_id('send message').click() + + sleep(3) + + value = driver.find_elements_by_xpath('//android.widget.EditText')[0].text + + assert value != None + event = json.loads(value) + + assert event['event_id'] != None + assert event['level'] == 'warning' + +def test_throw_error(driver): + driver.find_element_by_accessibility_id('throw error').click() + driver.relaunch_app() + value = driver.find_elements_by_xpath('//android.widget.EditText')[0].text + # the crash should have been already sent + assert value is None + +def test_native_crash(driver): + sleep(2) + driver.find_element_by_accessibility_id('native crash').click() + driver.relaunch_app() + sleep(3) + value = driver.find_elements_by_xpath('//android.widget.EditText')[0].text + + assert value != None + event = json.loads(value) + + assert event['event_id'] != None + assert event['level'] == 'fatal' diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index e70aeaf3ec..e0c4cd5dd4 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -28,18 +28,6 @@ def test_throw_error(driver): value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") # the crash should have been already sent assert value is None - # event = json.loads(value) - - # assert len(event['breadcrumbs']) > 0 - # assert len(event['contexts']) > 0 - # assert event['exception']['values'][0]['value'] == 'Sentry: Test throw error' - # assert event['platform'] == 'cocoa' - # assert event['level'] == 'fatal' - # assert event['dist'] == '1' - # assert event['logger'] == 'javascript' - # assert event['extra']['react'] - # assert event['tags']['react'] == '1' - # assert len(event['user']) > 0 def test_native_crash(driver): sleep(2) From dbc738c9baf5ac637fd9ff56b40f8c9213fbcc40 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 15:52:53 +0200 Subject: [PATCH 26/34] Update travis to export android home --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1dfa91f29c..5dc5d71147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,9 @@ before_install: - brew update - brew install yarn - brew outdated yarn || brew upgrade yarn + - export ANDROID_HOME=$PWD/android-sdk-macosx + - export ANDROID_SDK=$ANDROID_HOME + - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools script: - .travis/run.sh env: From 24d12c4df929f7c9c40829908ddebbb78e5fdeff Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 1 Aug 2017 17:05:06 +0200 Subject: [PATCH 27/34] Fix ios tests --- appium/tests/test_ios.py | 1 - ios/RNSentry.m | 24 +++++++++++------------- ios/Sentry | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index e0c4cd5dd4..8214ff5e60 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -18,7 +18,6 @@ def test_send_message(driver): assert event['message'] == 'TEST message' assert event['extra']['react'] assert event['tags']['react'] == '1' - assert event['sdk'] == False assert event['sdk']['integrations'][0] == 'react-native' assert len(event['user']) > 0 diff --git a/ios/RNSentry.m b/ios/RNSentry.m index 184e9a0e80..8b067850f3 100644 --- a/ios/RNSentry.m +++ b/ios/RNSentry.m @@ -175,9 +175,7 @@ - (void)setReleaseVersionDist:(SentryEvent *)event { if (event.extra[@"__sentry_dist"]) { event.dist = [NSString stringWithFormat:@"%@", event.extra[@"__sentry_dist"]]; } - NSMutableDictionary *prevExtra = SentryClient.sharedClient.extra.mutableCopy; - [prevExtra setValue:@[@"react-native"] forKey:@"__sentry_sdk_integrations"]; - SentryClient.sharedClient.extra = prevExtra; + [event.extra setValue:@[@"react-native"] forKey:@"__sentry_sdk_integrations"]; } RCT_EXPORT_MODULE() @@ -193,12 +191,11 @@ - (void)setReleaseVersionDist:(SentryEvent *)event { dispatch_once(&onceStartToken, ^{ NSError *error = nil; SentryClient *client = [[SentryClient alloc] initWithDsn:dsnString didFailWithError:&error]; - [SentryClient setSharedClient:client]; - [SentryClient.sharedClient startCrashHandlerWithError:&error]; - if (error) { - [NSException raise:@"SentryReactNative" format:@"%@", error.localizedDescription]; - } - SentryClient.sharedClient.shouldSendEvent = ^BOOL(SentryEvent * _Nonnull event) { + client.beforeSerializeEvent = ^(SentryEvent * _Nonnull event) { + [self injectReactNativeFrames:event]; + [self setReleaseVersionDist:event]; + }; + client.shouldSendEvent = ^BOOL(SentryEvent * _Nonnull event) { // We don't want to send an event after startup that came from a NSException of react native // Because we sent it already before the app crashed. if (nil != event.exceptions.firstObject.type && @@ -208,10 +205,11 @@ - (void)setReleaseVersionDist:(SentryEvent *)event { } return YES; }; - SentryClient.sharedClient.beforeSerializeEvent = ^(SentryEvent * _Nonnull event) { - [self injectReactNativeFrames:event]; - [self setReleaseVersionDist:event]; - }; + [SentryClient setSharedClient:client]; + [SentryClient.sharedClient startCrashHandlerWithError:&error]; + if (error) { + [NSException raise:@"SentryReactNative" format:@"%@", error.localizedDescription]; + } }); } diff --git a/ios/Sentry b/ios/Sentry index 6065445322..08ecf30e5a 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit 6065445322edd5cb3024d9a8b0e4995feeffb8ab +Subproject commit 08ecf30e5a448f62e07480ce6faed2006bd13bfa From 3646477d12504598e834424127732be0957b2c24 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 09:25:58 +0200 Subject: [PATCH 28/34] Change travis to build android --- .travis.yml | 63 ++++++++++++++++++++++++++++----------- SentryReactNative.podspec | 4 +-- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5dc5d71147..490d6ccc61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,47 @@ -language: objective-c -osx_image: xcode8.3 -cache: - - bundler - - pip -before_install: - - brew update - - brew install yarn - - brew outdated yarn || brew upgrade yarn - - export ANDROID_HOME=$PWD/android-sdk-macosx - - export ANDROID_SDK=$ANDROID_HOME - - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools -script: - - .travis/run.sh -env: - matrix: - - LANE=ios - - LANE=android +matrix: + include: + - language: android + os: linux + jdk: oraclejdk8 + before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + sudo: required + node_js: false + before_install: + - nvm install 7 + - node --version + - travis_retry curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - + - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list + - travis_retry sudo apt-get update -qq + - travis_retry sudo apt-get install -y -qq yarn + install: + - yarn + android: + components: + - build-tools-23.0.1 + - android-23 + - extra-android-m2repository + - extra-google-google_play_services + - extra-google-m2repository + - addon-google_apis-google-16 + script: + - .travis/run.sh + - language: objective-c + os: osx + osx_image: xcode8.3 + cache: + - bundler + - pip + env: + - LANE='ios' + before_install: + - brew update + - brew install yarn + - brew outdated yarn || brew upgrade yarn + install: + - travis_retry gem install fastlane + script: + - .travis/run.sh notifications: email: false diff --git a/SentryReactNative.podspec b/SentryReactNative.podspec index 40e2e79b4f..4210ebe14b 100644 --- a/SentryReactNative.podspec +++ b/SentryReactNative.podspec @@ -18,8 +18,8 @@ Pod::Spec.new do |s| s.preserve_paths = '*.js' s.dependency 'React' - s.dependency 'Sentry', '~> 3.1.3' - s.dependency 'Sentry/KSCrash', '~> 3.1.3' + s.dependency 'Sentry', '~> 3.3.3' + s.dependency 'Sentry/KSCrash', '~> 3.3.3' s.source_files = 'ios/RNSentry*.{h,m}' s.public_header_files = 'ios/RNSentry.h' From 01943b8bc9d934c7f8d8058896d0c0fabd2ea11e Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 10:13:14 +0200 Subject: [PATCH 29/34] Fix travis run script --- .travis.yml | 13 ++++++++++--- .travis/run.sh | 1 - README.md | 3 ++- appium/check_run_failues.rb | 22 +++++++++++++++------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 490d6ccc61..c0c599e0d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,13 @@ matrix: jdk: oraclejdk8 before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + - rm -rf $HOME/.gradle/caches/*/plugin-resolution/ + cache: + directories: + - $HOME/.yarn-cache + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ sudo: required - node_js: false before_install: - nvm install 7 - node --version @@ -17,6 +21,7 @@ matrix: - travis_retry sudo apt-get install -y -qq yarn install: - yarn + - bundle install android: components: - build-tools-23.0.1 @@ -31,6 +36,8 @@ matrix: os: osx osx_image: xcode8.3 cache: + directories: + - $HOME/.yarn-cache - bundler - pip env: @@ -40,7 +47,7 @@ matrix: - brew install yarn - brew outdated yarn || brew upgrade yarn install: - - travis_retry gem install fastlane + - bundle install script: - .travis/run.sh notifications: diff --git a/.travis/run.sh b/.travis/run.sh index e61c5b11f8..76fa2f5a11 100755 --- a/.travis/run.sh +++ b/.travis/run.sh @@ -9,4 +9,3 @@ then else make test-android fi -fastlane $LANE diff --git a/README.md b/README.md index 0dc6bffea5..f34d727726 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@
-

react-native-sentry

+

Sentry SDK for React Native

+[![Travis](https://img.shields.io/travis/getsentry/react-native-sentry.svg?maxAge=2592000)](https://travis-ci.org/getsentry/react-native-sentry) [![npm version](https://img.shields.io/npm/v/react-native-sentry.svg)](https://www.npmjs.com/package/react-native-sentry) [![npm dm](https://img.shields.io/npm/dm/react-native-sentry.svg)](https://www.npmjs.com/package/react-native-sentry) [![npm dt](https://img.shields.io/npm/dt/react-native-sentry.svg)](https://www.npmjs.com/package/react-native-sentry) diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index a69a4c7e76..dd2be19743 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -20,19 +20,27 @@ def android_check type: "FILE", arn: p.problems[0].test.arn }) - puts artifacts.inspect artifacts.artifacts.each do |a| if a.name == 'Logcat' content = open(a.url).read - raise RuntimeError, "Missing value raven: #{p.inspect}" unless content.scan(/"Raven about to send:', {"/).size == 1 + raise RuntimeError, "Missing value raven: #{p.inspect}" unless content.scan(/Raven about to send:/).size == 1 + raise RuntimeError, "Missing value: #{p.inspect}" unless content.scan(/value: 'Sentry: Test throw error'/).size == 1 + end + end + end + if p.problems[0].test.name == 'test_native_crash' + artifacts = @client.list_artifacts({ + type: "FILE", + arn: p.problems[0].test.arn + }) + artifacts.artifacts.each do |a| + if a.name == 'Logcat' + content = open(a.url).read + raise RuntimeError, "Missing native crash: #{p.inspect}" unless content.scan(/java.lang.RuntimeException: TEST - Sentry Client Crash/).size == 1 + raise RuntimeError, "Must start twice: #{p.inspect}" unless content.scan(/startWithDsnString/).size == 2 end end end - # if p.problems[0].test.name == 'test_native_crash' - # exception = p.message.match(/crashed: EXC_/) - # raise RuntimeError, "No crash: #{p.inspect}" unless !exception.nil? - # exception = nil - # end end end end From 870b112f99fdfda830f599f726384f8d6f7fee22 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 10:14:36 +0200 Subject: [PATCH 30/34] Fix cache folder --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c0c599e0d2..7665939cb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,8 +36,6 @@ matrix: os: osx osx_image: xcode8.3 cache: - directories: - - $HOME/.yarn-cache - bundler - pip env: From d4f7feac23e1a19df7f8c919d8c324c2ada2aec2 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 10:20:43 +0200 Subject: [PATCH 31/34] Remove bundle install --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7665939cb2..42fbfa1a1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,6 @@ matrix: - travis_retry sudo apt-get install -y -qq yarn install: - yarn - - bundle install android: components: - build-tools-23.0.1 @@ -44,8 +43,6 @@ matrix: - brew update - brew install yarn - brew outdated yarn || brew upgrade yarn - install: - - bundle install script: - .travis/run.sh notifications: From 1db218ba566875826f628df38dc7e531d13c42aa Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 10:24:07 +0200 Subject: [PATCH 32/34] Remove inital yarn install --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 42fbfa1a1e..fe6165d732 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,8 +19,6 @@ matrix: - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list - travis_retry sudo apt-get update -qq - travis_retry sudo apt-get install -y -qq yarn - install: - - yarn android: components: - build-tools-23.0.1 From 138cab978566abf2ee57ffd6f7993bfde3cf9a45 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 10:37:09 +0200 Subject: [PATCH 33/34] Fix android check test --- appium/check_run_failues.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/appium/check_run_failues.rb b/appium/check_run_failues.rb index dd2be19743..44272e0465 100644 --- a/appium/check_run_failues.rb +++ b/appium/check_run_failues.rb @@ -37,7 +37,6 @@ def android_check if a.name == 'Logcat' content = open(a.url).read raise RuntimeError, "Missing native crash: #{p.inspect}" unless content.scan(/java.lang.RuntimeException: TEST - Sentry Client Crash/).size == 1 - raise RuntimeError, "Must start twice: #{p.inspect}" unless content.scan(/startWithDsnString/).size == 2 end end end From 0f4d5c72dc7dca24fe8bb9d0927e541eec39b68c Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 2 Aug 2017 12:50:06 +0200 Subject: [PATCH 34/34] Add version tests --- .vscode/.ropeproject/config.py | 100 +++++++++++++++++++++++++++++++++ appium/tests/test_ios.py | 46 ++++++++++++--- examples | 2 +- 3 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 .vscode/.ropeproject/config.py diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py new file mode 100644 index 0000000000..d1e8f3df19 --- /dev/null +++ b/.vscode/.ropeproject/config.py @@ -0,0 +1,100 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git', '.tox'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + #prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + #prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + #prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will sort imports alphabetically by module name + # instead of alphabetically by import statement, with from imports + # after normal imports. + prefs['sort_imports_alphabetically'] = False + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/appium/tests/test_ios.py b/appium/tests/test_ios.py index 8214ff5e60..d4ff07bfba 100644 --- a/appium/tests/test_ios.py +++ b/appium/tests/test_ios.py @@ -3,16 +3,17 @@ from time import sleep -def test_send_message(driver): - driver.find_element_by_accessibility_id('send message').click() - sleep(3) +def extractText(driver): + return driver.find_element_by_accessibility_id('textarea').get_attribute("value") - value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") +def test_send_message(driver): + driver.find_element_by_accessibility_id('send message').click() + sleep(3) + value = extractText(driver) assert value != None event = json.loads(value) - assert len(event['breadcrumbs']) > 0 assert len(event['contexts']) > 0 assert event['message'] == 'TEST message' @@ -21,10 +22,41 @@ def test_send_message(driver): assert event['sdk']['integrations'][0] == 'react-native' assert len(event['user']) > 0 + +def test_version(driver): + driver.find_element_by_accessibility_id('set version').click() + driver.find_element_by_accessibility_id('send message').click() + sleep(3) + value = extractText(driver) + assert value != None + event = json.loads(value) + assert event['release'] == 'org.reactjs.native.example.AwesomeProject-1337' + + +def test_release(driver): + driver.find_element_by_accessibility_id('set release').click() + driver.find_element_by_accessibility_id('send message').click() + sleep(3) + value = extractText(driver) + assert value != None + event = json.loads(value) + assert event['release'] == 'myversion' + + +def test_dist(driver): + driver.find_element_by_accessibility_id('set dist').click() + driver.find_element_by_accessibility_id('send message').click() + sleep(3) + value = extractText(driver) + assert value != None + event = json.loads(value) + assert event['dist'] == '500' + + def test_throw_error(driver): driver.find_element_by_accessibility_id('throw error').click() driver.relaunch_app() - value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") + value = extractText(driver) # the crash should have been already sent assert value is None @@ -33,7 +65,7 @@ def test_native_crash(driver): driver.find_element_by_accessibility_id('native crash').click() driver.relaunch_app() sleep(3) - value = driver.find_element_by_accessibility_id('textarea').get_attribute("value") + value = extractText(driver) # the crash should have been already sent assert value != None event = json.loads(value) diff --git a/examples b/examples index ff5edb45ee..68fa357fd7 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit ff5edb45ee5b794d22a72687f8e31dcdac6d54bd +Subproject commit 68fa357fd7d85ebf404936d53f3c98a4947fcffe