ci: run apps/automated on CI (#9196)

This commit is contained in:
Igor Randjelovic
2021-02-05 20:21:16 +01:00
committed by GitHub
parent abc78800f2
commit 4945702620
13 changed files with 182 additions and 97 deletions

39
.github/workflows/apps_automated.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: 'apps/automated'
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
jobs:
test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Install Python
uses: actions/setup-python@v1
- name: Install NativeScript
run: |
python -m pip install --upgrade pip six
npm i -g nativescript --ignore-scripts
ns usage-reporting disable
ns error-reporting disable
ns doctor
- name: Setup
run: npm run setup
- name: Create Emulator
uses: rigor789/action-create-emulator@master
- name: Test (Android)
run: node tools/scripts/run-automated.js android
- name: Test (iOS)
if: always() # run iOS tests even if Android tests failed
run: node tools/scripts/run-automated.js ios

1
apps/automated/src/globals.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare var __CI__;

View File

@ -41,16 +41,18 @@ allTests['PLATFORM'] = platformTests;
import * as fsTests from './file-system/file-system-tests';
allTests['FILE-SYSTEM'] = fsTests;
// Disabled tests as they have external dependencies
// TODO: find a way to run these tests locally, but don't run them on the CI as they are flaky
// import * as httpTests from "./http/http-tests";
// allTests["HTTP"] = httpTests;
import * as httpTests from './http/http-tests';
import * as xhrTests from './xhr/xhr-tests';
import * as fetchTests from './fetch/fetch-tests';
import * as timerTests from './timer/timer-tests';
// import * as xhrTests from "./xhr/xhr-tests";
// allTests["XHR"] = xhrTests;
// import * as fetchTests from "./fetch/fetch-tests";
// allTests["FETCH"] = fetchTests;
// don't run these on CI as they are flaky
if (!__CI__) {
allTests['HTTP'] = httpTests;
allTests['XHR'] = xhrTests;
allTests['FETCH'] = fetchTests;
allTests['TIMER'] = timerTests;
}
import * as appSettingsTests from './application-settings/application-settings-tests';
allTests['APPLICATION-SETTINGS'] = appSettingsTests;
@ -70,9 +72,6 @@ allTests['VIRTUAL-ARRAY'] = virtualArrayTests;
import * as observableTests from './data/observable-tests';
allTests['OBSERVABLE'] = observableTests;
import * as timerTests from './timer/timer-tests';
allTests['TIMER'] = timerTests;
import * as animationFrameTests from './animation-frame/animation-frame';
allTests['ANIMATION-FRAME'] = animationFrameTests;

View File

@ -155,6 +155,7 @@ export function test_setInterval_callbackCalledDuringPeriod(done) {
export function test_setInterval_callbackCalledWithExtraArgs(done) {
let counter: number = 0;
const rnd: number = Math.random();
const threshold = 100;
const start = TKUnit.time();
const id = timer.setInterval(
@ -163,10 +164,10 @@ export function test_setInterval_callbackCalledWithExtraArgs(done) {
if (counter === 4) {
const end = TKUnit.time();
timer.clearInterval(id);
done(end - start > 250 ? new Error('setInterval too slow.') : null);
done(end - start > 1000 + threshold ? new Error('setInterval too slow.') : null);
}
},
50,
250,
rnd
);
}
@ -179,11 +180,11 @@ export function test_setInterval_callbackNotDelayedByBusyWork() {
calls++;
if (firstCall) {
firstCall = false;
TKUnit.wait(0.025);
TKUnit.wait(0.125);
}
}, 50);
}, 250);
TKUnit.wait(0.11);
TKUnit.wait(0.55);
timer.clearInterval(id);
TKUnit.assertEqual(calls, 2, 'Callback should be called multiple times with busy wait');
}

View File

@ -1,53 +1,53 @@
import * as buttonModule from '@nativescript/core/ui/button';
import * as colorModule from '@nativescript/core/color';
import * as utilsModule from '@nativescript/core/utils/utils';
import * as enums from '@nativescript/core/ui/enums';
import { Color, Button, Utils, Enums } from '@nativescript/core';
export function getNativeText(button: buttonModule.Button): string {
export function getNativeText(button: Button): string {
return button.android.getText();
}
export function getNativeTextWrap(button: buttonModule.Button): boolean {
export function getNativeTextWrap(button: Button): boolean {
return (<android.widget.Button>button.android).getLineCount() === 1;
}
export function getNativeFontSize(button: buttonModule.Button): number {
var density = utilsModule.layout.getDisplayDensity();
export function getNativeFontSize(button: Button): number {
let density = Utils.layout.getDisplayDensity();
return button.android.getTextSize() / density;
}
export function getNativeColor(button: buttonModule.Button): colorModule.Color {
return new colorModule.Color(button.android.getTextColors().getDefaultColor());
export function getNativeColor(button: Button): Color {
return new Color(button.android.getTextColors().getDefaultColor());
}
export function getNativeBackgroundColor(button: buttonModule.Button): colorModule.Color {
var bkg = <any>button.android.getBackground();
if (bkg instanceof org.nativescript.widgets.BorderDrawable) {
return new colorModule.Color((<org.nativescript.widgets.BorderDrawable>bkg).getBackgroundColor());
export function getNativeBackgroundColor(button: Button): Color {
let bg = <any>button.android.getBackground();
if (bg instanceof org.nativescript.widgets.BorderDrawable) {
return new Color(bg.getBackgroundColor());
} else if (bg instanceof android.graphics.drawable.ColorDrawable) {
console.log(bg);
return new Color(bg.getColor());
} else {
return new colorModule.Color(bkg.backgroundColor);
return new Color(bg.backgroundColor);
}
}
export function getNativeTextAlignment(button: buttonModule.Button): string {
var gravity = button.android.getGravity();
export function getNativeTextAlignment(button: Button): string {
let gravity = button.android.getGravity();
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) {
return enums.TextAlignment.left;
return Enums.TextAlignment.left;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) {
return enums.TextAlignment.center;
return Enums.TextAlignment.center;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) {
return enums.TextAlignment.right;
return Enums.TextAlignment.right;
}
return 'unexpected value';
}
export function performNativeClick(button: buttonModule.Button): void {
export function performNativeClick(button: Button): void {
button.android.performClick();
}

View File

@ -3,7 +3,7 @@ import * as enums from '@nativescript/core/ui/enums';
import * as colorModule from '@nativescript/core/color';
export function getNativeTextAlignment(label: labelModule.Label): string {
var gravity = label.android.getGravity();
let gravity = label.android.getGravity();
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) {
return enums.TextAlignment.left;
@ -21,10 +21,12 @@ export function getNativeTextAlignment(label: labelModule.Label): string {
}
export function getNativeBackgroundColor(label: labelModule.Label): colorModule.Color {
var bkg = <any>label.android.getBackground();
if (bkg instanceof org.nativescript.widgets.BorderDrawable) {
return new colorModule.Color((<org.nativescript.widgets.BorderDrawable>bkg).getBackgroundColor());
let bg = <any>label.android.getBackground();
if (bg instanceof org.nativescript.widgets.BorderDrawable) {
return new colorModule.Color(bg.getBackgroundColor());
} else if (bg instanceof android.graphics.drawable.ColorDrawable) {
return new colorModule.Color(bg.getColor());
} else {
return new colorModule.Color(bkg.backgroundColor);
return new colorModule.Color(bg.backgroundColor);
}
}

View File

@ -330,8 +330,8 @@ export class LabelTest extends testModule.UITest<LabelModule.Label> {
normalColor = actualColors.getDefaultColor();
TKUnit.assert(normalColor, 'Expected: ' + expColor + ', Actual: ' + normalColor);
const bkg = <org.nativescript.widgets.BorderDrawable>testLabel.android.getBackground();
actualBackgroundColor = bkg.getBackgroundColor();
const bg = testLabel.android.getBackground();
actualBackgroundColor = bg['getBackgroundColor'] ? bg.getBackgroundColor() : bg.getColor();
expBackgroundColor = android.graphics.Color.parseColor(backgroundColor);
TKUnit.assertEqual(actualBackgroundColor, expBackgroundColor);
} else {

View File

@ -1,74 +1,74 @@
import * as textFieldModule from '@nativescript/core/ui/text-field';
import * as colorModule from '@nativescript/core/color';
import * as utilsModule from '@nativescript/core/utils/utils';
import * as enums from '@nativescript/core/ui/enums';
import { TextField, Color, Utils, Enums } from '@nativescript/core';
export function getNativeText(textField: textFieldModule.TextField): string {
export function getNativeText(textField: TextField): string {
return textField.android.getText().toString();
}
export function getNativeHint(textField: textFieldModule.TextField): string {
export function getNativeHint(textField: TextField): string {
return textField.android.getHint();
}
export function getNativeSecure(textField: textFieldModule.TextField): boolean {
var inputType = textField.android.getInputType();
export function getNativeSecure(textField: TextField): boolean {
let inputType = textField.android.getInputType();
return (inputType & android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD) === android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD || (inputType & android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD) === android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD;
}
export function getNativeFontSize(textField: textFieldModule.TextField): number {
var density = utilsModule.layout.getDisplayDensity();
export function getNativeFontSize(textField: TextField): number {
let density = Utils.layout.getDisplayDensity();
return textField.android.getTextSize() / density;
}
export function getNativeColor(textField: textFieldModule.TextField): colorModule.Color {
return new colorModule.Color(textField.android.getTextColors().getDefaultColor());
export function getNativeColor(textField: TextField): Color {
return new Color(textField.android.getTextColors().getDefaultColor());
}
export function getNativePlaceholderColor(textField: textFieldModule.TextField): colorModule.Color {
return new colorModule.Color(textField.android.getHintTextColors().getDefaultColor());
export function getNativePlaceholderColor(textField: TextField): Color {
return new Color(textField.android.getHintTextColors().getDefaultColor());
}
export function getNativeBackgroundColor(textField: textFieldModule.TextField): colorModule.Color {
var bkg = <any>textField.android.getBackground();
if (bkg instanceof org.nativescript.widgets.BorderDrawable) {
return new colorModule.Color((<org.nativescript.widgets.BorderDrawable>bkg).getBackgroundColor());
export function getNativeBackgroundColor(textField: TextField): Color {
let bg = <any>textField.android.getBackground();
if (bg instanceof org.nativescript.widgets.BorderDrawable) {
return new Color(bg.getBackgroundColor());
} else if (bg instanceof android.graphics.drawable.ColorDrawable) {
console.log(bg);
return new Color(bg.getColor());
} else {
return new colorModule.Color(bkg.backgroundColor);
return new Color(bg.backgroundColor);
}
}
export function getNativeTextAlignment(textField: textFieldModule.TextField): string {
export function getNativeTextAlignment(textField: TextField): string {
var gravity = textField.android.getGravity();
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) {
return enums.TextAlignment.left;
return Enums.TextAlignment.left;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) {
return enums.TextAlignment.center;
return Enums.TextAlignment.center;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) {
return enums.TextAlignment.right;
return Enums.TextAlignment.right;
}
return 'unexpected value';
}
export function getNativeFocus(textField: textFieldModule.TextField): boolean {
export function getNativeFocus(textField: TextField): boolean {
//
return true;
}
export function typeTextNatively(textField: textFieldModule.TextField, text: string): void {
export function typeTextNatively(textField: TextField, text: string): void {
textField.android.requestFocus();
textField.android.setText(text);
textField.android.clearFocus();
}
export function typeTextNativelyWithReturn(textField: textFieldModule.TextField, text: string): void {
export function typeTextNativelyWithReturn(textField: TextField, text: string): void {
//
}

View File

@ -1,13 +1,10 @@
import * as textViewModule from '@nativescript/core/ui/text-view';
import * as colorModule from '@nativescript/core/color';
import * as utilsModule from '@nativescript/core/utils/utils';
import * as enums from '@nativescript/core/ui/enums';
import { TextView, Color, Utils, Enums } from '@nativescript/core';
export function getNativeText(textView: textViewModule.TextView): string {
export function getNativeText(textView: TextView): string {
return textView.android.getText().toString();
}
export function getNativeEditable(textView: textViewModule.TextView): boolean {
export function getNativeEditable(textView: TextView): boolean {
if (textView.android.getKeyListener()) {
return true;
} else {
@ -15,53 +12,55 @@ export function getNativeEditable(textView: textViewModule.TextView): boolean {
}
}
export function getNativeHint(textView: textViewModule.TextView): string {
export function getNativeHint(textView: TextView): string {
return textView.android.getHint();
}
export function getNativeFontSize(textView: textViewModule.TextView): number {
var density = utilsModule.layout.getDisplayDensity();
export function getNativeFontSize(textView: TextView): number {
let density = Utils.layout.getDisplayDensity();
return textView.android.getTextSize() / density;
}
export function getNativeColor(textView: textViewModule.TextView): colorModule.Color {
return new colorModule.Color(textView.android.getTextColors().getDefaultColor());
export function getNativeColor(textView: TextView): Color {
return new Color(textView.android.getTextColors().getDefaultColor());
}
export function getNativeBackgroundColor(textView: textViewModule.TextView): colorModule.Color {
var bkg = <any>textView.android.getBackground();
if (bkg instanceof org.nativescript.widgets.BorderDrawable) {
return new colorModule.Color((<org.nativescript.widgets.BorderDrawable>bkg).getBackgroundColor());
export function getNativeBackgroundColor(textView: TextView): Color {
let bg = <any>textView.android.getBackground();
if (bg instanceof org.nativescript.widgets.BorderDrawable) {
return new Color(bg.getBackgroundColor());
} else if (bg instanceof android.graphics.drawable.ColorDrawable) {
return new Color(bg.getColor());
} else {
return new colorModule.Color(bkg.backgroundColor);
return new Color(bg.backgroundColor);
}
}
export function getNativeTextAlignment(textView: textViewModule.TextView): string {
var gravity = textView.android.getGravity();
export function getNativeTextAlignment(textView: TextView): string {
let gravity = textView.android.getGravity();
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) {
return enums.TextAlignment.left;
return Enums.TextAlignment.left;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) {
return enums.TextAlignment.center;
return Enums.TextAlignment.center;
}
if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) {
return enums.TextAlignment.right;
return Enums.TextAlignment.right;
}
return 'unexpected value';
}
export function typeTextNatively(textView: textViewModule.TextView, text: string): void {
export function typeTextNatively(textView: TextView, text: string): void {
textView.android.requestFocus();
textView.android.setText(text);
textView.android.clearFocus();
}
export function getNativeMaxLines(textView: textViewModule.TextView): number {
export function getNativeMaxLines(textView: TextView): number {
return textView.android.getMaxLines();
}

View File

@ -1,6 +1,8 @@
const webpackConfig = require('./webpack.config');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpackConfig = require('./webpack.config');
module.exports = (env) => {
env = env || {};
const baseConfig = webpackConfig(env);
@ -9,5 +11,9 @@ module.exports = (env) => {
{ from: { glob: 'ui/web-view/*.html', dot: false } }
]))
baseConfig.plugins.push(new webpack.DefinePlugin({
__CI__: !!process.env.CI
}))
return baseConfig;
};

View File

@ -55,6 +55,7 @@
"reduce-css-calc": "~2.1.7",
"shady-css-parser": "^0.1.0",
"terser-webpack-plugin": "~3.0.6",
"tree-kill": "^1.2.2",
"ts-jest": "26.4.0",
"ts-node": "~8.10.2",
"ts-patch": "^1.2.5",

View File

@ -45,12 +45,13 @@ export namespace ad {
androidView._cachedDrawable = constantState || drawable;
}
const isBorderDrawable = drawable instanceof org.nativescript.widgets.BorderDrawable;
const isColorDrawable = drawable instanceof android.graphics.drawable.ColorDrawable;
const onlyColor = !background.hasBorderWidth() && !background.hasBorderRadius() && !background.clipPath && !background.image && !!background.color;
if (drawable instanceof android.graphics.drawable.ColorDrawable && onlyColor) {
if (!isBorderDrawable && isColorDrawable && onlyColor) {
drawable.setColor(background.color.android);
drawable.invalidateSelf();
} else if (isSetColorFilterOnlyWidget(nativeView) && drawable && onlyColor) {
if (drawable instanceof org.nativescript.widgets.BorderDrawable && androidView._cachedDrawable) {
if (isBorderDrawable && androidView._cachedDrawable) {
if (!(androidView._cachedDrawable instanceof android.graphics.drawable.Drawable.ConstantState)) {
return;
}

View File

@ -0,0 +1,36 @@
/**
* Script to run the automated tests & exit after the tests are finished.
* Mainly intended to be used on CI
*
* Usage: node run-automated.js <platform>
*/
const spawn = require('child_process').spawn
const kill = require('tree-kill');
const spawned_process = spawn('npm', ['start', `apps.automated.${process.argv[2]}`], {
stdio: ['inherit', 'pipe', 'pipe']
})
const {stdout, stderr} = spawned_process
stdout.pipe(process.stdout)
stderr.pipe(process.stderr)
let lineBuffer = []
stdout.on('data', data => {
const line = data.toString();
// start buffering lines when tests are complete
if(lineBuffer.length || line.includes('=== ALL TESTS COMPLETE ===')) {
lineBuffer.push(line)
}
if(line.includes('Tests EOF!')) {
let ok = lineBuffer.join('\n').includes('OK, 0 failed')
console.log(ok ? 'Tests PASSED' : 'Tests FAILED');
kill(spawned_process.pid)
process.exit(ok ? 0 : 1)
}
})