diff --git a/.gitignore b/.gitignore index c8f50f7..080e9cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ npm-debug.log +.idea/ +AwesomeProject +android/.gradle +android/.idea +android/build +android/local.properties +node_modules diff --git a/.travis.yml b/.travis.yml index d702bfa..0ddbf96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,8 @@ script: - pod install - #xcrun xcodebuild -quiet -workspace AwesomeProject.xcworkspace -scheme AwesomeProject -configuration Debug CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO | xcpretty before_deploy: -- ANDROID_SDK_VERSION=1.12.4 -- IOS_VERSION=1.28.3 +- ANDROID_SDK_VERSION=1.12.5 +- IOS_VERSION=1.28.4 - cd ../.. - rm -rf AwesomeProject - sed -i '' "s/\"version\":.*/\"version\":\"${TRAVIS_TAG}\",/g" package.json diff --git a/android/build.gradle b/android/build.gradle index f698512..d39e5f5 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -19,7 +19,7 @@ android { dependencies { api 'com.facebook.react:react-native:+' - api 'com.testfairy:testfairy-android-sdk:1.12.3@aar' + api 'com.testfairy:testfairy-android-sdk:1.12.5@aar' } class TestFairyRepositoryPlugin implements Plugin { diff --git a/android/src/main/java/com/testfairy/react/TestFairyModule.java b/android/src/main/java/com/testfairy/react/TestFairyModule.java index c8edbdb..5836613 100644 --- a/android/src/main/java/com/testfairy/react/TestFairyModule.java +++ b/android/src/main/java/com/testfairy/react/TestFairyModule.java @@ -1,5 +1,6 @@ package com.testfairy.react; +import android.content.Context; import android.util.Log; import android.view.View; @@ -16,13 +17,18 @@ import com.testfairy.FeedbackOptions; import com.testfairy.TestFairy; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; public class TestFairyModule extends ReactContextBaseJavaModule { private static class TFOnMultipleViewsFoundListenerProxy implements java.lang.reflect.InvocationHandler { @@ -419,7 +425,6 @@ public void run() { } } - if (options.hasKey("isEmailMandatory")) { ReadableType isEmailMandatoryType = options.getType("isEmailMandatory"); if (isEmailMandatoryType == ReadableType.Boolean) { @@ -436,7 +441,42 @@ public void run() { } }); } - + + @ReactMethod + public void attachFile(final String filename, final String content) { + if (filename == null) { + throw new RuntimeException("Cannot attach file without a name!"); + } + + runOnUi(new Runnable() { + @Override + public void run() { + Context context = getReactApplicationContext(); + File outputDir = context.getCacheDir(); + try { + File tfTemp = new File(outputDir, "tfTemp"); + if (tfTemp.exists()) { + deleteDir(tfTemp); + } + + tfTemp.mkdir(); + + File outputFile = new File(tfTemp, filename); + FileOutputStream fileOutputStream = new FileOutputStream(outputFile); + + if (content != null) { + fileOutputStream.write(content.getBytes(Charset.forName("UTF-8"))); + } + + fileOutputStream.close(); + + TestFairy.attachFile(outputFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } private Map convertMap(ReadableMap map) { Map input = new HashMap(); @@ -506,4 +546,19 @@ private ArrayList convertArray(ReadableArray array) { private void runOnUi(Runnable runnable) { UiThreadUtil.runOnUiThread(runnable); } + + // To delete all contents recursively, like rm -rf + private static boolean deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + for (int i = 0; i < children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + return false; + } + } + } + + return dir.delete(); + } } diff --git a/index.js b/index.js index 9f3915d..daaa5d5 100644 --- a/index.js +++ b/index.js @@ -326,7 +326,7 @@ class TestFairy { } /** - * Customize the feedback form + * Customize the feedback form. * * Accepted dictionary values: { * "defaultText": , @@ -345,6 +345,17 @@ class TestFairy { static setFeedbackOptions(options) { TestFairyBridge.setFeedbackOptions(options); } + + /** + * Attach a file to the session timeline at current moment in time. + * + * @param filename Name of the attached file. It must have a file extension. + * @param content A utf-8 javascript string, can be empty. + * @param mimeType MIME type of the given file, i.e "text/plain" + */ + static attachFile(filename, content, mimeType) { + TestFairyBridge.attachFile(filename, content); + } } // var _testfairyConsoleLog = console.log; diff --git a/ios/RCTTestFairyBridge.m b/ios/RCTTestFairyBridge.m index 15ee4b6..602958c 100644 --- a/ios/RCTTestFairyBridge.m +++ b/ios/RCTTestFairyBridge.m @@ -29,9 +29,9 @@ @implementation RCTTestFairyBridge } RCT_EXPORT_METHOD(identify:(NSString *)correlationId traits:(NSDictionary *)traits) { - dispatch_async(dispatch_get_main_queue(), ^{ - [TestFairy identify:correlationId traits:traits]; - }); + dispatch_async(dispatch_get_main_queue(), ^{ + [TestFairy identify:correlationId traits:traits]; + }); } RCT_EXPORT_METHOD(takeScreenshot) { @@ -250,4 +250,26 @@ @implementation RCTTestFairyBridge }); } -@end +RCT_EXPORT_METHOD(attachFile:(NSString *)filename content:(NSString *)content) { + dispatch_async(dispatch_get_main_queue(), ^{ + NSString* tfTempPath = @"tfTemp"; + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSURL* tfTemp = nil; + + if (@available(iOS 10, *)) { + tfTemp = [fileManager.temporaryDirectory URLByAppendingPathComponent:tfTempPath]; + } else { + tfTemp = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:tfTempPath]]; + } + + [fileManager removeItemAtURL:tfTemp error:nil]; + [fileManager createDirectoryAtURL:tfTemp withIntermediateDirectories:YES attributes:nil error:nil]; + + NSURL* url = [tfTemp URLByAppendingPathComponent:filename]; + [[RCTConvert NSData:content] writeToURL:url atomically:YES]; + + [TestFairy attachFile:url]; + }); +} + +@end \ No newline at end of file diff --git a/package.json b/package.json index 37e066e..0f12b52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-testfairy", - "version": "2.45.0", + "version": "2.46.0", "description": "TestFairy for React Native", "main": "./index.js", "scripts": {