Skip to content

feat: verify console logs #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ max-public-methods=25
max-returns=6

# Maximum number of statements in function / method body.
max-statements=50
max-statements=75

# Minimum number of public methods for a class (see R0903).
min-public-methods=2
Expand Down
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ script:
- python -m nose core_tests/utils -v -s --nologcapture --with-doctest --with-xunit
- python -m flake8 --max-line-length=120 core core_tests data products tests
- python -m pylint --disable=locally-disabled --rcfile=.pylintrc core data products
- find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
- find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
- find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
- find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ python -m pylint --disable=locally-disabled --rcfile=.pylintrc core data product
Due to the fact tests are not modules pylint can not be executed directly.
Workaround:
```bash
find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
```

## Hints, Tips and Tricks
Expand Down
93 changes: 93 additions & 0 deletions core_tests/products/sync_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import unittest

from core.enums.platform_type import Platform
from core.settings import Settings
from products.nativescript.run_type import RunType
from products.nativescript.tns_logs import TnsLogs


# noinspection PyMethodMayBeStatic
class SyncMessagesTests(unittest.TestCase):

def test_01_constants(self):
assert len(TnsLogs.SKIP_NODE_MODULES) == 2

def test_02_get_prepare_messages(self):
logs = TnsLogs.prepare_messages(platform=Platform.ANDROID, plugins=['tns-core-modules', 'fake-plugin'])
assert 'Preparing project...' in logs
assert 'Successfully prepared plugin tns-core-modules for android' in logs
assert 'Successfully prepared plugin fake-plugin for android' in logs
assert 'Project successfully prepared (Android)' in logs
assert len(logs) == 4

def test_02_get_run_messages_first_run(self):
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
platform=Platform.ANDROID,
run_type=RunType.FIRST_TIME)
# assert 'Skipping node_modules folder!' in logs
# assert 'Preparing project...' in logs
# assert 'Project successfully prepared (Android)' in logs
# assert 'Building project...' in logs
# assert 'Gradle build...' in logs
# assert 'Project successfully built.' in logs
# assert 'Installing on device' in logs
# assert 'Successfully installed on device' in logs
assert 'Restarting application on device' in logs
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
assert 'ActivityManager: Start proc' in logs
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs

def test_03_get_run_messages_sync_js(self):
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
platform=Platform.ANDROID,
run_type=RunType.INCREMENTAL,
file_name='main-view-model.js')
assert 'Preparing project...' in logs
assert 'Project successfully prepared (Android)' in logs
assert 'Successfully transferred main-view-model.js on device' in logs
assert 'Restarting application on device' in logs
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
assert 'ActivityManager: Start proc' in logs
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs

def test_04_get_run_messages_sync_js_bundle(self):
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
platform=Platform.ANDROID,
run_type=RunType.INCREMENTAL,
file_name='main-view-model.js',
bundle=True)
assert 'File change detected.' in logs
assert 'main-view-model.js' in logs
assert 'Webpack compilation complete.' in logs
assert 'Preparing project...' in logs
assert 'Project successfully prepared (Android)' in logs
assert 'Successfully transferred bundle.js on device' in logs
assert 'Restarting application on device' in logs
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
assert 'ActivityManager: Start proc' in logs
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs
assert 'Refreshing application on device' not in logs
assert 'hot-update.json on device' not in logs

def test_05_get_run_messages_sync_js_hmr(self):
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
platform=Platform.ANDROID,
run_type=RunType.INCREMENTAL,
file_name='main-view-model.js',
hmr=True)
assert 'File change detected.' in logs
assert 'main-view-model.js' in logs
assert 'Webpack compilation complete.' in logs
assert 'hot-update.json on device' in logs
assert 'The following modules were updated:' in logs
assert 'Successfully applied update with hmr hash' in logs
# TODO: Uncomment when fixed in TnsLogs.run_messages()
# assert 'Refreshing application on device' in logs
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
assert 'Successfully transferred bundle.js on device' not in logs
# TODO: Uncomment when fixed in TnsLogs.run_messages()
# assert 'Restarting application on device' not in logs


if __name__ == '__main__':
unittest.main()
33 changes: 19 additions & 14 deletions core_tests/products/tns_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,23 @@
from nose.tools import timed

from core.base_test.tns_test import TnsTest
from core.enums.os_type import OSType
from core.enums.platform_type import Platform
from core.settings import Settings
from core.utils.device.device_manager import DeviceManager
from data.apps import Apps
from products.nativescript.run_type import RunType
from products.nativescript.tns import Tns
from products.nativescript.tns_helpers import TnsHelpers
from products.nativescript.tns_logs import TnsLogs


class TnsTests(TnsTest):
app_name = Settings.AppName.DEFAULT
app_folder = os.path.join(Settings.TEST_RUN_HOME, app_name)
emu = None
sim = None
app_folder = os.path.join(Settings.TEST_RUN_HOME, Settings.AppName.DEFAULT)

@classmethod
def setUpClass(cls):
TnsTest.setUpClass()
Tns.create(app_name=cls.app_name)
Tns.create(app_name=Settings.AppName.DEFAULT)
cls.emu = DeviceManager.Emulator.ensure_available(Settings.Emulators.DEFAULT)
if Settings.HOST_OS is OSType.OSX:
cls.sim = DeviceManager.Simulator.ensure_available(Settings.Simulators.DEFAULT)

def setUp(self):
TnsTest.setUp(self)
Expand All @@ -37,20 +34,28 @@ def tearDownClass(cls):

@timed(300)
def test_001_tns_run_android(self):
result = Tns.run_android(app_name=self.app_name, device=self.emu.id, wait=False)
result = Tns.run_android(app_name=Settings.AppName.DEFAULT, device=self.emu.id, wait=False)

# Verify result object
assert result.complete is False, 'tns run with wait false should not complete after command above is executed.'
assert result.exit_code is None, 'tns run with wait false is hav eno exit code since it is not complete.'
assert result.log_file is not None, 'stdout and stderr should be redirected to file.'

# Wait until app is build and installed.
texts = ['Project successfully built', 'Successfully installed']
TnsHelpers.wait_for_log(result.log_file, texts)
# Verify console logs of `tns run` command
plugins = ['nativescript-theme-core', 'tns-core-modules', 'tns-core-modules-widgets']
messages = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
platform=Platform.ANDROID,
run_type=RunType.FIRST_TIME,
plugins=plugins)
TnsLogs.wait_for_log(result.log_file, messages)

# Verify app looks ok
for text in Apps.HELLO_WORLD_JS.texts:
self.emu.wait_for_text(text=text)

@timed(300)
def test_002_tns_run_android_with_justlaunch(self):
result = Tns.run_android(app_name=self.app_name, device=self.emu.id, justlaunch=True, wait=True)
result = Tns.run_android(app_name=Settings.AppName.DEFAULT, device=self.emu.id, justlaunch=True, wait=True)
assert result.complete is True, 'tns run with --justlauch and wait=true should wait until command is executed.'
assert result.exit_code == 0, 'tns run should be successful.'
assert 'Successfully synced application' in result.output
4 changes: 2 additions & 2 deletions data/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Apps(object):
SCHEMATICS_SHARED = AppInfo(app_type=AppType.SHARED_NG, app_id=None, size=__shared_size, texts=['Welcome'])
SCHEMATICS_SHARED_SAMPLE = AppInfo(app_type=AppType.SHARED_NG, app_id=None, size=__shared_size, texts=['Barcelona'])
SCHEMATICS_NS = AppInfo(app_type=AppType.NG, app_id=None, size=__ns_only_size, texts=['Tap the button'])
HELLO_WORLD_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=None)
HELLO_WORLD_TS = AppInfo(app_type=AppType.TS, app_id=None, size=None, texts=None)
HELLO_WORLD_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=['Tap the button'])
HELLO_WORLD_TS = AppInfo(app_type=AppType.TS, app_id=None, size=None, texts=['Tap the button'])
HELLO_WORLD_NG = AppInfo(app_type=AppType.NG, app_id=None, size=None, texts=None)
MIN_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=None)
16 changes: 16 additions & 0 deletions data/issues/liveSyncJS/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
In NativeScript, the app.js file is the entry point to your application.
You can use this file to perform app-level initialization, but the primary
purpose of the file is to pass control to the app’s first module.
*/

var application = require("tns-core-modules/application");
application.on(application.launchEvent, () => {
console.log("application started");
});
application.run({ moduleName: "app-root" });

/*
Do not place any code after the application has been started as it will not
be executed on iOS.
*/
22 changes: 22 additions & 0 deletions data/issues/liveSyncNG/items.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component, OnInit } from "@angular/core";

import { Item } from "./item";
import { ItemService } from "./item.service";

@Component({
selector: "ns-items",
moduleId: module.id,
templateUrl: "./items.component.html",
})
export class ItemsComponent implements OnInit {
items: Item[];

// This pattern makes use of Angular’s dependency injection implementation to inject an instance of the ItemService service into this class.
// Angular knows about this service because it is included in your app’s main NgModule, defined in app.module.ts.
constructor(private itemService: ItemService) { }

ngOnInit(): void {
console.log("items component on init");
this.items = this.itemService.getItems();
}
}
14 changes: 14 additions & 0 deletions data/issues/liveSyncNG/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// this import should be first in order to load some required settings (like globals and reflect-metadata)
import { platformNativeScriptDynamic } from "nativescript-angular/platform";

import { AppModule } from "./app/app.module";

import * as application from "tns-core-modules/application";
application.on(application.launchEvent, () => {
console.log("applications started");
});
// A traditional NativeScript application starts by initializing global objects, setting up global CSS rules, creating, and navigating to the main page.
// Angular applications need to take care of their own initialization: modules, components, directives, routes, DI providers.
// A NativeScript Angular app needs to make both paradigms work together, so we provide a wrapper platform object, platformNativeScriptDynamic,
// that sets up a NativeScript application and can bootstrap the Angular framework.
platformNativeScriptDynamic().bootstrapModule(AppModule);
17 changes: 17 additions & 0 deletions data/issues/liveSyncTS/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
In NativeScript, the app.ts file is the entry point to your application.
You can use this file to perform app-level initialization, but the primary
purpose of the file is to pass control to the app’s first module.
*/

import * as application from "tns-core-modules/application";
application.on(application.launchEvent, () => {
console.log("application started");
})

application.run({ moduleName: "app-root" });

/*
Do not place any code after the application has been started as it will not
be executed on iOS.
*/
24 changes: 24 additions & 0 deletions data/sync/hello_world_js.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
from core.utils.wait import Wait
from data.changes import Changes, Sync
from data.const import Colors
from products.nativescript.run_type import RunType
from products.nativescript.tns import Tns
from products.nativescript.tns_logs import TnsLogs


def sync_hello_world_js(app_name, platform, device, bundle=False, hmr=False, uglify=False, aot=False,
Expand Down Expand Up @@ -56,6 +58,10 @@ def __sync_hello_world_js_ts(app_type, app_name, platform, device,
bundle=bundle, hmr=hmr, uglify=uglify, aot=aot, snapshot=snapshot)
__verify_snapshot_skipped(snapshot, result)

strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr)
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

# Verify it looks properly
device.wait_for_text(text=js_change.old_text, timeout=120, retry_delay=5)
device.wait_for_text(text=xml_change.old_text)
Expand All @@ -67,31 +73,49 @@ def __sync_hello_world_js_ts(app_type, app_name, platform, device,
# Edit JS file and verify changes are applied
Sync.replace(app_name=app_name, change_set=js_change)
device.wait_for_text(text=js_change.new_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='main-view-model.js')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

# Edit XML file and verify changes are applied
Sync.replace(app_name=app_name, change_set=xml_change)
device.wait_for_text(text=xml_change.new_text)
device.wait_for_text(text=js_change.new_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='main-page.xml')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

# Edit CSS file and verify changes are applied
Sync.replace(app_name=app_name, change_set=css_change)
device.wait_for_color(color=Colors.LIGHT_BLUE, pixel_count=blue_count * 2, delta=25)
device.wait_for_text(text=xml_change.new_text)
device.wait_for_text(text=js_change.new_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='app.css')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

# Revert all the changes
Sync.revert(app_name=app_name, change_set=js_change)
device.wait_for_text(text=js_change.old_text)
device.wait_for_text(text=xml_change.new_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='main-view-model.js')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

Sync.revert(app_name=app_name, change_set=xml_change)
device.wait_for_text(text=xml_change.old_text)
device.wait_for_text(text=js_change.old_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='main-page.xml')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

Sync.revert(app_name=app_name, change_set=css_change)
device.wait_for_color(color=Colors.LIGHT_BLUE, pixel_count=blue_count)
device.wait_for_text(text=xml_change.old_text)
device.wait_for_text(text=js_change.old_text)
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
hmr=hmr, file_name='app.css')
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)

# Assert final and initial states are same
device.screen_match(expected_image=initial_state, tolerance=1.0, timeout=30)
Loading