Open sourced SwipeRefreshLayoutRecordingModule
Reviewed By: dmmiller Differential Revision: D3264212 fb-gh-sync-id: 8790200a0d3c47050d6a91c906854b3a55640829 fbshipit-source-id: 8790200a0d3c47050d6a91c906854b3a55640829
This commit is contained in:
parent
a1ba0918ab
commit
457e348081
|
@ -5,31 +5,41 @@ include_defs('//ReactAndroid/DEFS')
|
||||||
SANDCASTLE_FLAKY = [
|
SANDCASTLE_FLAKY = [
|
||||||
'ReactHorizontalScrollViewTestCase.java',
|
'ReactHorizontalScrollViewTestCase.java',
|
||||||
'ReactScrollViewTestCase.java',
|
'ReactScrollViewTestCase.java',
|
||||||
|
'ReactSwipeRefreshLayoutTestCase.java',
|
||||||
|
'TestIdTestCase.java',
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
|
||||||
|
react_native_target('java/com/facebook/react/bridge:bridge'),
|
||||||
|
react_native_target('java/com/facebook/react/uimanager:uimanager'),
|
||||||
|
react_native_target('java/com/facebook/react/views/picker:picker'),
|
||||||
|
react_native_target('java/com/facebook/react/views/swiperefresh:swiperefresh'),
|
||||||
|
react_native_target('java/com/facebook/react:react'),
|
||||||
|
react_native_target('java/com/facebook/react/common:common'),
|
||||||
|
react_native_target('java/com/facebook/react/views/progressbar:progressbar'),
|
||||||
|
react_native_target('java/com/facebook/react/views/recyclerview:recyclerview'),
|
||||||
|
react_native_target('java/com/facebook/react/views/scroll:scroll'),
|
||||||
|
react_native_target('java/com/facebook/react/views/slider:slider'),
|
||||||
|
react_native_target('java/com/facebook/react/views/text:text'),
|
||||||
|
react_native_target('java/com/facebook/react/views/textinput:textinput'),
|
||||||
|
react_native_target('java/com/facebook/react/views/view:view'),
|
||||||
|
react_native_dep('third-party/android/support/v4:lib-support-v4'),
|
||||||
]
|
]
|
||||||
|
|
||||||
android_library(
|
android_library(
|
||||||
name = 'tests',
|
name = 'tests',
|
||||||
srcs = glob(['**/*.java']),
|
srcs = glob(['**/*.java']),
|
||||||
deps = [
|
|
||||||
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
|
|
||||||
react_native_target('java/com/facebook/react/bridge:bridge'),
|
|
||||||
react_native_target('java/com/facebook/react/uimanager:uimanager'),
|
|
||||||
react_native_target('java/com/facebook/react/views/picker:picker'),
|
|
||||||
],
|
|
||||||
visibility = [
|
visibility = [
|
||||||
'PUBLIC',
|
'PUBLIC',
|
||||||
],
|
],
|
||||||
|
deps = deps,
|
||||||
)
|
)
|
||||||
|
|
||||||
android_library(
|
android_library(
|
||||||
name = 'stable-tests',
|
name = 'stable-tests',
|
||||||
srcs = glob(['**/*.java'], excludes=SANDCASTLE_FLAKY),
|
srcs = glob(['**/*.java'], excludes=SANDCASTLE_FLAKY),
|
||||||
deps = [
|
deps = deps,
|
||||||
react_native_integration_tests_target('java/com/facebook/react/testing:testing'),
|
|
||||||
react_native_target('java/com/facebook/react/bridge:bridge'),
|
|
||||||
react_native_target('java/com/facebook/react/uimanager:uimanager'),
|
|
||||||
react_native_target('java/com/facebook/react/views/picker:picker'),
|
|
||||||
],
|
|
||||||
visibility = [
|
visibility = [
|
||||||
'PUBLIC',
|
'PUBLIC',
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.facebook.react.tests;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
|
||||||
|
import com.facebook.react.testing.ReactInstanceSpecForTest;
|
||||||
|
import com.facebook.react.bridge.BaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.JavaScriptModule;
|
||||||
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
import com.facebook.react.views.swiperefresh.ReactSwipeRefreshLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case for {@link ReactSwipeRefreshLayout}.
|
||||||
|
*/
|
||||||
|
public class ReactSwipeRefreshLayoutTestCase extends ReactAppInstrumentationTestCase {
|
||||||
|
|
||||||
|
private class SwipeRefreshLayoutRecordingModule extends BaseJavaModule {
|
||||||
|
private int mCount = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "SwipeRefreshLayoutRecordingModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void onRefresh() {
|
||||||
|
mCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return mCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface SwipeRefreshLayoutTestModule extends JavaScriptModule {
|
||||||
|
void setRows(int rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SwipeRefreshLayoutRecordingModule mRecordingModule =
|
||||||
|
new SwipeRefreshLayoutRecordingModule();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getReactApplicationKeyUnderTest() {
|
||||||
|
return "SwipeRefreshLayoutTestApp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
|
||||||
|
return super.createReactInstanceSpecForTest()
|
||||||
|
.addNativeModule(mRecordingModule)
|
||||||
|
.addJSModule(SwipeRefreshLayoutTestModule.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRefreshNoScroll() {
|
||||||
|
View refreshLayout = getViewAtPath(0);
|
||||||
|
|
||||||
|
createGestureGenerator()
|
||||||
|
.startGesture(refreshLayout.getWidth() / 2, 10)
|
||||||
|
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
|
||||||
|
.endGesture();
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
assertEquals(1, mRecordingModule.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRefreshScroll() {
|
||||||
|
View refreshLayout = getViewAtPath(0);
|
||||||
|
|
||||||
|
getReactContext().getJSModule(SwipeRefreshLayoutTestModule.class).setRows(100);
|
||||||
|
|
||||||
|
createGestureGenerator()
|
||||||
|
.startGesture(refreshLayout.getWidth() / 2, 10)
|
||||||
|
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
|
||||||
|
.endGesture();
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
assertEquals(1, mRecordingModule.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoRefreshAfterScroll() {
|
||||||
|
View refreshLayout = getViewAtPath(0);
|
||||||
|
|
||||||
|
getReactContext().getJSModule(SwipeRefreshLayoutTestModule.class).setRows(100);
|
||||||
|
|
||||||
|
createGestureGenerator()
|
||||||
|
.startGesture(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2)
|
||||||
|
.dragTo(refreshLayout.getWidth() / 2, 10, 100, 1000)
|
||||||
|
.endGesture();
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
createGestureGenerator()
|
||||||
|
.startGesture(refreshLayout.getWidth() / 2, 10)
|
||||||
|
.dragTo(refreshLayout.getWidth() / 2, refreshLayout.getHeight() / 2, 100, 1000)
|
||||||
|
.endGesture();
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
assertEquals(0, mRecordingModule.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.facebook.react.tests;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.facebook.react.views.picker.ReactDropdownPickerManager;
|
||||||
|
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
|
||||||
|
import com.facebook.react.testing.ReactInstanceSpecForTest;
|
||||||
|
import com.facebook.react.testing.ReactTestHelper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that the 'testID' property can be set on various views.
|
||||||
|
* The 'testID' property is used to locate views in UI tests.
|
||||||
|
*/
|
||||||
|
public class TestIdTestCase extends ReactAppInstrumentationTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getReactApplicationKeyUnderTest() {
|
||||||
|
return "TestIdTestApp";
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<String> viewTags = Arrays.asList(
|
||||||
|
"Image",
|
||||||
|
"ProgressBar",
|
||||||
|
"ScrollView",
|
||||||
|
"Horizontal ScrollView",
|
||||||
|
"Dropdown Picker",
|
||||||
|
"Dialog Picker",
|
||||||
|
"Switch",
|
||||||
|
"Text",
|
||||||
|
"TouchableBounce",
|
||||||
|
"TouchableHighlight",
|
||||||
|
"TouchableOpacity",
|
||||||
|
"TouchableWithoutFeedback",
|
||||||
|
"Toolbar",
|
||||||
|
"TextInput",
|
||||||
|
"View",
|
||||||
|
"WebView",
|
||||||
|
"ScrollView Item (same id used for all items)");
|
||||||
|
|
||||||
|
public void testPropertyIsSetForViews() {
|
||||||
|
for (String tag : viewTags) {
|
||||||
|
View viewWithTag = ReactTestHelper.getViewWithReactTestId(
|
||||||
|
getActivity().getRootView(),
|
||||||
|
tag);
|
||||||
|
assertNotNull(
|
||||||
|
"View with testID tag " + tag + " was not found. Check TestIdTestModule.js.",
|
||||||
|
viewWithTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.facebook.react.tests;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.JavaScriptModule;
|
||||||
|
import com.facebook.react.common.SystemClock;
|
||||||
|
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
|
||||||
|
import com.facebook.react.testing.ReactInstanceSpecForTest;
|
||||||
|
import com.facebook.react.uimanager.PixelUtil;
|
||||||
|
import com.facebook.react.uimanager.UIManagerModule;
|
||||||
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||||
|
import com.facebook.react.views.textinput.ReactEditText;
|
||||||
|
import com.facebook.react.views.textinput.ReactTextChangedEvent;
|
||||||
|
import com.facebook.react.views.textinput.ReactTextInputEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to verify that TextInput renders correctly
|
||||||
|
*/
|
||||||
|
public class TextInputTestCase extends ReactAppInstrumentationTestCase {
|
||||||
|
|
||||||
|
private interface TextInputTestModule extends JavaScriptModule {
|
||||||
|
void setValueRef(String ref, String value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the actual height of the text input is not dependant on the font size of the text
|
||||||
|
* within.
|
||||||
|
*/
|
||||||
|
public void testTextInputMeasurements() {
|
||||||
|
View textInputViewHeightSet = getViewByTestId("textInput1");
|
||||||
|
EditText textInputViewNoHeight = getViewByTestId("textInput2");
|
||||||
|
|
||||||
|
int expectedHeight = Math.round(PixelUtil.toPixelFromDIP(30));
|
||||||
|
assertEquals(expectedHeight, textInputViewHeightSet.getHeight());
|
||||||
|
|
||||||
|
EditText editText = new EditText(textInputViewNoHeight.getContext());
|
||||||
|
editText.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
|
(float) Math.ceil(PixelUtil.toPixelFromSP(21.f)));
|
||||||
|
editText.setPadding(0, 0, 0, 0);
|
||||||
|
int measureSpec = View.MeasureSpec.makeMeasureSpec(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
View.MeasureSpec.UNSPECIFIED);
|
||||||
|
editText.measure(measureSpec, measureSpec);
|
||||||
|
|
||||||
|
assertEquals(editText.getMeasuredHeight(), textInputViewNoHeight.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the cursor moves to the end of the word.
|
||||||
|
*/
|
||||||
|
public void testTextInputCursorPosition() throws Throwable {
|
||||||
|
final EditText textInputWithText = getViewByTestId("textInput3");
|
||||||
|
|
||||||
|
runTestOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
textInputWithText.setSelection(3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getReactContext().getJSModule(TextInputTestModule.class)
|
||||||
|
.setValueRef("textInput3", "Some other value");
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
|
||||||
|
assertEquals(4, textInputWithText.getSelectionStart());
|
||||||
|
assertEquals(4, textInputWithText.getSelectionEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the colors are applied to new text
|
||||||
|
*/
|
||||||
|
public void testTextInputColors() throws Throwable {
|
||||||
|
String testIDs[] = new String[] {"textInput4", "textInput5", "textInput6"};
|
||||||
|
|
||||||
|
for (String testID : testIDs) {
|
||||||
|
getReactContext().getJSModule(TextInputTestModule.class).setValueRef(testID, "NewText");
|
||||||
|
}
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
|
||||||
|
for (String testID : testIDs) {
|
||||||
|
ReactEditText reactEditText = getViewByTestId(testID);
|
||||||
|
assertEquals(
|
||||||
|
Color.GREEN,
|
||||||
|
reactEditText.getText().getSpans(0, 1, ForegroundColorSpan.class)[0]
|
||||||
|
.getForegroundColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that the mentions input has colors displayed correctly.
|
||||||
|
*/
|
||||||
|
public void testMetionsInputColors() throws Throwable {
|
||||||
|
EventDispatcher eventDispatcher =
|
||||||
|
getReactContext().getNativeModule(UIManagerModule.class).getEventDispatcher();
|
||||||
|
ReactEditText reactEditText = getViewByTestId("tokenizedInput");
|
||||||
|
String newText = "#Things and more #things";
|
||||||
|
int contentWidth = reactEditText.getWidth();
|
||||||
|
int contentHeight = reactEditText.getHeight();
|
||||||
|
int start = 0;
|
||||||
|
int count = newText.length();
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextChangedEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
newText.toString(),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentWidth),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentHeight),
|
||||||
|
reactEditText.incrementAndGetEventCounter()));
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextInputEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
newText.toString(),
|
||||||
|
"",
|
||||||
|
start,
|
||||||
|
start + count - 1));
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
|
||||||
|
ForegroundColorSpan[] spans = reactEditText
|
||||||
|
.getText().getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
|
||||||
|
assertEquals(2, spans.length);
|
||||||
|
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
|
||||||
|
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
|
||||||
|
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
|
||||||
|
assertEquals(newText.length() - 7, reactEditText.getText().getSpanStart(spans[0]));
|
||||||
|
assertEquals(newText.length(), reactEditText.getText().getSpanEnd(spans[0]));
|
||||||
|
|
||||||
|
String moreText = "andsuch ";
|
||||||
|
String previousText = newText;
|
||||||
|
newText += moreText;
|
||||||
|
count = moreText.length();
|
||||||
|
start = previousText.length();
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextChangedEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
newText.toString(),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentWidth),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentHeight),
|
||||||
|
reactEditText.incrementAndGetEventCounter()));
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextInputEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
moreText,
|
||||||
|
"",
|
||||||
|
start,
|
||||||
|
start + count - 1));
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
|
||||||
|
spans = reactEditText.getText()
|
||||||
|
.getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
|
||||||
|
assertEquals(2, spans.length);
|
||||||
|
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
|
||||||
|
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
|
||||||
|
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
|
||||||
|
assertEquals(newText.length() - 15, reactEditText.getText().getSpanStart(spans[0]));
|
||||||
|
assertEquals(newText.length() - 1, reactEditText.getText().getSpanEnd(spans[0]));
|
||||||
|
|
||||||
|
moreText = "morethings";
|
||||||
|
previousText = newText;
|
||||||
|
newText += moreText;
|
||||||
|
count = moreText.length();
|
||||||
|
start = previousText.length();
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextChangedEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
newText.toString(),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentWidth),
|
||||||
|
(int) PixelUtil.toDIPFromPixel(contentHeight),
|
||||||
|
reactEditText.incrementAndGetEventCounter()));
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(
|
||||||
|
new ReactTextInputEvent(
|
||||||
|
reactEditText.getId(),
|
||||||
|
SystemClock.nanoTime(),
|
||||||
|
moreText,
|
||||||
|
"",
|
||||||
|
start,
|
||||||
|
start + count - 1));
|
||||||
|
waitForBridgeAndUIIdle();
|
||||||
|
|
||||||
|
spans = reactEditText.getText()
|
||||||
|
.getSpans(0, reactEditText.getText().length(), ForegroundColorSpan.class);
|
||||||
|
assertEquals(spans[0].getForegroundColor(), spans[1].getForegroundColor());
|
||||||
|
assertEquals(2, spans.length);
|
||||||
|
assertEquals(0, reactEditText.getText().getSpanStart(spans[1]));
|
||||||
|
assertEquals(7, reactEditText.getText().getSpanEnd(spans[1]));
|
||||||
|
assertEquals(newText.length() - 25, reactEditText.getText().getSpanStart(spans[0]));
|
||||||
|
assertEquals(newText.length() - 11, reactEditText.getText().getSpanEnd(spans[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
|
||||||
|
return super.createReactInstanceSpecForTest()
|
||||||
|
.addJSModule(TextInputTestModule.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getReactApplicationKeyUnderTest() {
|
||||||
|
return "TextInputTestApp";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @providesModule SwipeRefreshLayoutTestModule
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var BatchedBridge = require('BatchedBridge');
|
||||||
|
var React = require('React');
|
||||||
|
var RecordingModule = require('NativeModules').SwipeRefreshLayoutRecordingModule;
|
||||||
|
var ScrollView = require('ScrollView');
|
||||||
|
var PullToRefreshViewAndroid = require('PullToRefreshViewAndroid');
|
||||||
|
var Text = require('Text');
|
||||||
|
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
|
||||||
|
var View = require('View');
|
||||||
|
|
||||||
|
var Row = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
clicks: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<TouchableWithoutFeedback onPress={this._onPress}>
|
||||||
|
<View>
|
||||||
|
<Text>
|
||||||
|
{this.state.clicks + ' clicks'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPress: function() {
|
||||||
|
this.setState({clicks: this.state.clicks + 1});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var app = null;
|
||||||
|
var SwipeRefreshLayoutTestApp = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
rows: 2,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
app = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
var rows = [];
|
||||||
|
for (var i = 0; i < this.state.rows; i++) {
|
||||||
|
rows.push(<Row key={i} />);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<PullToRefreshViewAndroid
|
||||||
|
style={{flex: 1}}
|
||||||
|
onRefresh={() => RecordingModule.onRefresh()}>
|
||||||
|
<ScrollView style={{flex: 1}}>
|
||||||
|
{rows}
|
||||||
|
</ScrollView>
|
||||||
|
</PullToRefreshViewAndroid>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var SwipeRefreshLayoutTestModule = {
|
||||||
|
SwipeRefreshLayoutTestApp,
|
||||||
|
setRows: function(rows) {
|
||||||
|
if (app != null) {
|
||||||
|
app.setState({rows});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BatchedBridge.registerCallableModule(
|
||||||
|
'SwipeRefreshLayoutTestModule',
|
||||||
|
SwipeRefreshLayoutTestModule
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = SwipeRefreshLayoutTestModule;
|
|
@ -15,15 +15,13 @@ console.disableYellowBox = true;
|
||||||
// Include modules used by integration tests
|
// Include modules used by integration tests
|
||||||
require('ScrollViewTestModule');
|
require('ScrollViewTestModule');
|
||||||
require('PickerAndroidTestModule');
|
require('PickerAndroidTestModule');
|
||||||
|
require('SwipeRefreshLayoutTestModule');
|
||||||
|
require('TextInputTestModule');
|
||||||
|
|
||||||
// Define catalyst test apps used in integration tests
|
// Define catalyst test apps used in integration tests
|
||||||
var AppRegistry = require('AppRegistry');
|
var AppRegistry = require('AppRegistry');
|
||||||
|
|
||||||
var apps = [
|
var apps = [
|
||||||
{
|
|
||||||
appKey: 'ScrollViewTestApp',
|
|
||||||
component: () => require('ScrollViewTestModule').ScrollViewTestApp,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
appKey: 'HorizontalScrollViewTestApp',
|
appKey: 'HorizontalScrollViewTestApp',
|
||||||
component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp,
|
component: () => require('ScrollViewTestModule').HorizontalScrollViewTestApp,
|
||||||
|
@ -32,7 +30,25 @@ var apps = [
|
||||||
appKey: 'PickerAndroidTestApp',
|
appKey: 'PickerAndroidTestApp',
|
||||||
component: () => require('PickerAndroidTestModule').PickerAndroidTestApp,
|
component: () => require('PickerAndroidTestModule').PickerAndroidTestApp,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
appKey: 'ScrollViewTestApp',
|
||||||
|
component: () => require('ScrollViewTestModule').ScrollViewTestApp,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
appKey: 'SwipeRefreshLayoutTestApp',
|
||||||
|
component: () => require('SwipeRefreshLayoutTestModule').SwipeRefreshLayoutTestApp
|
||||||
|
},
|
||||||
|
{
|
||||||
|
appKey: 'TextInputTestApp',
|
||||||
|
component: () => require('TextInputTestModule').TextInputTestApp
|
||||||
|
},
|
||||||
|
{
|
||||||
|
appKey: 'TestIdTestApp',
|
||||||
|
component: () => require('TestIdTestModule').TestIdTestApp
|
||||||
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
module.exports = apps;
|
module.exports = apps;
|
||||||
AppRegistry.registerConfig(apps);
|
AppRegistry.registerConfig(apps);
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @providesModule TestIdTestModule
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Image = require('Image');
|
||||||
|
var ProgressBarAndroid = require('ProgressBarAndroid');
|
||||||
|
var React = require('React');
|
||||||
|
var ScrollView = require('ScrollView');
|
||||||
|
var Picker = require('Picker');
|
||||||
|
var StyleSheet = require('StyleSheet');
|
||||||
|
var SwitchAndroid = require('SwitchAndroid');
|
||||||
|
var Text = require('Text');
|
||||||
|
var TextInput = require('TextInput');
|
||||||
|
var ToolbarAndroid = require('ToolbarAndroid');
|
||||||
|
var TouchableBounce = require('TouchableBounce');
|
||||||
|
var TouchableHighlight = require('TouchableHighlight');
|
||||||
|
var TouchableOpacity = require('TouchableOpacity');
|
||||||
|
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
|
||||||
|
var View = require('View');
|
||||||
|
var WebView = require('WebView');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All the views implemented on Android, each with the testID property set.
|
||||||
|
* We test that:
|
||||||
|
* - The app renders fine
|
||||||
|
* - The testID property is passed to the native views
|
||||||
|
*/
|
||||||
|
var TestIdTestApp = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
testID="Image"
|
||||||
|
source={{uri: 'data:image/gif;base64,' +
|
||||||
|
'R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapy' +
|
||||||
|
'uvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/' +
|
||||||
|
'TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5' +
|
||||||
|
'iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97V' +
|
||||||
|
'riy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7'}}
|
||||||
|
style={styles.base} />
|
||||||
|
|
||||||
|
<ProgressBarAndroid
|
||||||
|
testID="ProgressBar"
|
||||||
|
styleAttr="Horizontal"
|
||||||
|
style={styles.base} />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
testID="ScrollView"
|
||||||
|
style={styles.base}>
|
||||||
|
<Text testID="ScrollView Item (same id used for all items)">Item 1</Text>
|
||||||
|
<Text testID="ScrollView Item (same id used for all items)">Item 2</Text>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
testID="Horizontal ScrollView"
|
||||||
|
horizontal={true}
|
||||||
|
style={styles.base}>
|
||||||
|
<Text testID="ScrollView Item (same id used for all items)">Item 1</Text>
|
||||||
|
<Text testID="ScrollView Item (same id used for all items)">Item 2</Text>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<Picker
|
||||||
|
testID="Dropdown Picker"
|
||||||
|
mode={Picker.MODE_DROPDOWN}
|
||||||
|
style={styles.base}>
|
||||||
|
<Picker.Item label="Dropdown picker" value="key0" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<Picker
|
||||||
|
testID="Dialog Picker"
|
||||||
|
mode={Picker.MODE_DIALOG}
|
||||||
|
style={styles.base}>
|
||||||
|
<Picker.Item label="Dialog picker" value="key0" />
|
||||||
|
</Picker>
|
||||||
|
|
||||||
|
<SwitchAndroid testID="Switch" value={true} />
|
||||||
|
|
||||||
|
<Text testID="Text">text</Text>
|
||||||
|
|
||||||
|
<ToolbarAndroid testID="Toolbar" style={styles.base} subtitle="toolbar" />
|
||||||
|
|
||||||
|
<TextInput testID="TextInput" value="Text input" />
|
||||||
|
|
||||||
|
<TouchableBounce testID="TouchableBounce">
|
||||||
|
<Text>TouchableBounce</Text>
|
||||||
|
</TouchableBounce>
|
||||||
|
|
||||||
|
<TouchableHighlight testID="TouchableHighlight">
|
||||||
|
<Text>TouchableHighlight</Text>
|
||||||
|
</TouchableHighlight>
|
||||||
|
|
||||||
|
<TouchableOpacity testID="TouchableOpacity">
|
||||||
|
<Text>TouchableOpacity</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableWithoutFeedback testID="TouchableWithoutFeedback">
|
||||||
|
<View>
|
||||||
|
<Text>TouchableWithoutFeedback</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableWithoutFeedback>
|
||||||
|
|
||||||
|
<View testID="View" />
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
testID="WebView"
|
||||||
|
url={'http://newsroom.fb.com'}
|
||||||
|
renderError={() => <View /> }
|
||||||
|
style={styles.base}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
base: {
|
||||||
|
width: 150,
|
||||||
|
height: 50,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
TestIdTestApp: TestIdTestApp,
|
||||||
|
};
|
|
@ -0,0 +1,170 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @providesModule TextInputTestModule
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var BatchedBridge = require('BatchedBridge');
|
||||||
|
var React = require('React');
|
||||||
|
var StyleSheet = require('StyleSheet');
|
||||||
|
var Text = require('Text');
|
||||||
|
var TextInput = require('TextInput');
|
||||||
|
var View = require('View');
|
||||||
|
|
||||||
|
var app;
|
||||||
|
|
||||||
|
class TokenizedTextExample extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {text: ''};
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
|
||||||
|
//define delimiter
|
||||||
|
let delimiter = /\s+/;
|
||||||
|
|
||||||
|
//split string
|
||||||
|
let _text = this.state.text;
|
||||||
|
let token, index, parts = [];
|
||||||
|
while (_text) {
|
||||||
|
delimiter.lastIndex = 0;
|
||||||
|
token = delimiter.exec(_text);
|
||||||
|
if (token === null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index = token.index;
|
||||||
|
if (token[0].length === 0) {
|
||||||
|
index = 1;
|
||||||
|
}
|
||||||
|
parts.push(_text.substr(0, index));
|
||||||
|
parts.push(token[0]);
|
||||||
|
index = index + token[0].length;
|
||||||
|
_text = _text.slice(index);
|
||||||
|
}
|
||||||
|
parts.push(_text);
|
||||||
|
|
||||||
|
//highlight hashtags
|
||||||
|
parts = parts.map((text) => {
|
||||||
|
if (/^#/.test(text)) {
|
||||||
|
return <Text key={text} style={styles.hashtag}>{text}</Text>;
|
||||||
|
} else {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<TextInput
|
||||||
|
ref="tokenizedInput"
|
||||||
|
testID="tokenizedInput"
|
||||||
|
multiline={true}
|
||||||
|
style={styles.multiline}
|
||||||
|
onChangeText={(text) => {
|
||||||
|
this.setState({text});
|
||||||
|
}}>
|
||||||
|
<Text>{parts}</Text>
|
||||||
|
</TextInput>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var TextInputTestApp = React.createClass({
|
||||||
|
componentDidMount: function() {
|
||||||
|
app = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.textInputHeight}
|
||||||
|
autoCorrect={true}
|
||||||
|
autoFocus={true}
|
||||||
|
keyboardType='numeric'
|
||||||
|
multiline={true}
|
||||||
|
password={true}
|
||||||
|
defaultValue="This is text"
|
||||||
|
testID="textInput1"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
style={styles.textInput}
|
||||||
|
autoCapitalize='sentences'
|
||||||
|
autoCorrect={false}
|
||||||
|
autoFocus={false}
|
||||||
|
keyboardType='default'
|
||||||
|
multiline={false}
|
||||||
|
password={false}
|
||||||
|
placeholder='1234'
|
||||||
|
testID="textInput2"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
ref="textInput3"
|
||||||
|
style={styles.textInput}
|
||||||
|
defaultValue="Hello, World"
|
||||||
|
testID="textInput3"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
ref="textInput4"
|
||||||
|
style={[styles.textInput, {color: '#00ff00'}]}
|
||||||
|
testID="textInput4"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
ref="textInput5"
|
||||||
|
style={[styles.textInput, {color: '#00ff00'}]}
|
||||||
|
defaultValue=""
|
||||||
|
testID="textInput5"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
ref="textInput6"
|
||||||
|
style={[styles.textInput, {color: '#00ff00'}]}
|
||||||
|
defaultValue="Text"
|
||||||
|
testID="textInput6"
|
||||||
|
/>
|
||||||
|
<TokenizedTextExample />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
padding: 5,
|
||||||
|
margin: 10,
|
||||||
|
},
|
||||||
|
textInputHeight: {
|
||||||
|
fontSize: 21,
|
||||||
|
height: 30,
|
||||||
|
},
|
||||||
|
textInput: {
|
||||||
|
fontSize: 21,
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
hashtag: {
|
||||||
|
color: 'blue',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var TextInputTestModule = {
|
||||||
|
TextInputTestApp,
|
||||||
|
setValueRef: function(ref, value) {
|
||||||
|
app.refs[ref].setNativeProps({
|
||||||
|
text: value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
BatchedBridge.registerCallableModule(
|
||||||
|
'TextInputTestModule',
|
||||||
|
TextInputTestModule
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = TextInputTestModule;
|
|
@ -3,6 +3,8 @@
|
||||||
# Runs all Android integration tests locally.
|
# Runs all Android integration tests locally.
|
||||||
# See http://facebook.github.io/react-native/docs/testing.html
|
# See http://facebook.github.io/react-native/docs/testing.html
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
which buck > /dev/null || {
|
which buck > /dev/null || {
|
||||||
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
|
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
|
||||||
exit 1;
|
exit 1;
|
||||||
|
@ -13,6 +15,7 @@ echo "Compiling native code..."
|
||||||
echo "Building JS bundle..."
|
echo "Building JS bundle..."
|
||||||
node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||||
echo "Installing test app on the device..."
|
echo "Installing test app on the device..."
|
||||||
|
buck fetch ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
|
||||||
buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
|
buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests
|
||||||
echo "Running integration tests..."
|
echo "Running integration tests..."
|
||||||
./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests
|
adb shell am instrument -w com.facebook.react.tests/android.support.test.runner.AndroidJUnitRunner
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
# Runs all Android unit tests locally.
|
# Runs all Android unit tests locally.
|
||||||
# See http://facebook.github.io/react-native/docs/testing.html
|
# See http://facebook.github.io/react-native/docs/testing.html
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
which buck > /dev/null || {
|
which buck > /dev/null || {
|
||||||
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
|
echo "React Native uses the Buck build tool to run tests. Please install Buck: https://buckbuild.com/setup/install.html";
|
||||||
exit 1;
|
exit 1;
|
||||||
|
|
Loading…
Reference in New Issue