Skip to content

Commit 5d239e0

Browse files
dtopuzovmiroslavaivanova
authored andcommitted
feat: verify console logs (#26)
* wip: tests for cli logs during run * tests: unit tests for log asserts * reafactor: methods for console log checks * fix: remove unused app * fix: lint * fix: failing test * new console logs * console logs for bundle and hmr * ts console logs * latest changes console logs * increase similarity lines * fix travis
1 parent bc5d704 commit 5d239e0

File tree

20 files changed

+694
-119
lines changed

20 files changed

+694
-119
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ max-public-methods=25
534534
max-returns=6
535535

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

539539
# Minimum number of public methods for a class (see R0903).
540540
min-public-methods=2

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ script:
1313
- python -m nose core_tests/utils -v -s --nologcapture --with-doctest --with-xunit
1414
- python -m flake8 --max-line-length=120 core core_tests data products tests
1515
- python -m pylint --disable=locally-disabled --rcfile=.pylintrc core data products
16-
- find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
17-
- find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
16+
- find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
17+
- find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ python -m pylint --disable=locally-disabled --rcfile=.pylintrc core data product
8585
Due to the fact tests are not modules pylint can not be executed directly.
8686
Workaround:
8787
```bash
88-
find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
89-
find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=15 --rcfile=.pylintrc
88+
find core_tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
89+
find tests | grep .py | grep -v .pyc | xargs python -m pylint --disable=locally-disabled --min-similarity-lines=20 --rcfile=.pylintrc
9090
```
9191

9292
## Hints, Tips and Tricks

core_tests/products/sync_tests.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import unittest
2+
3+
from core.enums.platform_type import Platform
4+
from core.settings import Settings
5+
from products.nativescript.run_type import RunType
6+
from products.nativescript.tns_logs import TnsLogs
7+
8+
9+
# noinspection PyMethodMayBeStatic
10+
class SyncMessagesTests(unittest.TestCase):
11+
12+
def test_01_constants(self):
13+
assert len(TnsLogs.SKIP_NODE_MODULES) == 2
14+
15+
def test_02_get_prepare_messages(self):
16+
logs = TnsLogs.prepare_messages(platform=Platform.ANDROID, plugins=['tns-core-modules', 'fake-plugin'])
17+
assert 'Preparing project...' in logs
18+
assert 'Successfully prepared plugin tns-core-modules for android' in logs
19+
assert 'Successfully prepared plugin fake-plugin for android' in logs
20+
assert 'Project successfully prepared (Android)' in logs
21+
assert len(logs) == 4
22+
23+
def test_02_get_run_messages_first_run(self):
24+
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
25+
platform=Platform.ANDROID,
26+
run_type=RunType.FIRST_TIME)
27+
# assert 'Skipping node_modules folder!' in logs
28+
# assert 'Preparing project...' in logs
29+
# assert 'Project successfully prepared (Android)' in logs
30+
# assert 'Building project...' in logs
31+
# assert 'Gradle build...' in logs
32+
# assert 'Project successfully built.' in logs
33+
# assert 'Installing on device' in logs
34+
# assert 'Successfully installed on device' in logs
35+
assert 'Restarting application on device' in logs
36+
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
37+
assert 'ActivityManager: Start proc' in logs
38+
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs
39+
40+
def test_03_get_run_messages_sync_js(self):
41+
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
42+
platform=Platform.ANDROID,
43+
run_type=RunType.INCREMENTAL,
44+
file_name='main-view-model.js')
45+
assert 'Preparing project...' in logs
46+
assert 'Project successfully prepared (Android)' in logs
47+
assert 'Successfully transferred main-view-model.js on device' in logs
48+
assert 'Restarting application on device' in logs
49+
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
50+
assert 'ActivityManager: Start proc' in logs
51+
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs
52+
53+
def test_04_get_run_messages_sync_js_bundle(self):
54+
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
55+
platform=Platform.ANDROID,
56+
run_type=RunType.INCREMENTAL,
57+
file_name='main-view-model.js',
58+
bundle=True)
59+
assert 'File change detected.' in logs
60+
assert 'main-view-model.js' in logs
61+
assert 'Webpack compilation complete.' in logs
62+
assert 'Preparing project...' in logs
63+
assert 'Project successfully prepared (Android)' in logs
64+
assert 'Successfully transferred bundle.js on device' in logs
65+
assert 'Restarting application on device' in logs
66+
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
67+
assert 'ActivityManager: Start proc' in logs
68+
assert 'activity org.nativescript.TestApp/com.tns.NativeScriptActivity' in logs
69+
assert 'Refreshing application on device' not in logs
70+
assert 'hot-update.json on device' not in logs
71+
72+
def test_05_get_run_messages_sync_js_hmr(self):
73+
logs = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
74+
platform=Platform.ANDROID,
75+
run_type=RunType.INCREMENTAL,
76+
file_name='main-view-model.js',
77+
hmr=True)
78+
assert 'File change detected.' in logs
79+
assert 'main-view-model.js' in logs
80+
assert 'Webpack compilation complete.' in logs
81+
assert 'hot-update.json on device' in logs
82+
assert 'The following modules were updated:' in logs
83+
assert 'Successfully applied update with hmr hash' in logs
84+
# TODO: Uncomment when fixed in TnsLogs.run_messages()
85+
# assert 'Refreshing application on device' in logs
86+
assert 'Successfully synced application org.nativescript.TestApp on device' in logs
87+
assert 'Successfully transferred bundle.js on device' not in logs
88+
# TODO: Uncomment when fixed in TnsLogs.run_messages()
89+
# assert 'Restarting application on device' not in logs
90+
91+
92+
if __name__ == '__main__':
93+
unittest.main()

core_tests/products/tns_tests.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@
33
from nose.tools import timed
44

55
from core.base_test.tns_test import TnsTest
6-
from core.enums.os_type import OSType
6+
from core.enums.platform_type import Platform
77
from core.settings import Settings
88
from core.utils.device.device_manager import DeviceManager
9+
from data.apps import Apps
10+
from products.nativescript.run_type import RunType
911
from products.nativescript.tns import Tns
10-
from products.nativescript.tns_helpers import TnsHelpers
12+
from products.nativescript.tns_logs import TnsLogs
1113

1214

1315
class TnsTests(TnsTest):
14-
app_name = Settings.AppName.DEFAULT
15-
app_folder = os.path.join(Settings.TEST_RUN_HOME, app_name)
16-
emu = None
17-
sim = None
16+
app_folder = os.path.join(Settings.TEST_RUN_HOME, Settings.AppName.DEFAULT)
1817

1918
@classmethod
2019
def setUpClass(cls):
2120
TnsTest.setUpClass()
22-
Tns.create(app_name=cls.app_name)
21+
Tns.create(app_name=Settings.AppName.DEFAULT)
2322
cls.emu = DeviceManager.Emulator.ensure_available(Settings.Emulators.DEFAULT)
24-
if Settings.HOST_OS is OSType.OSX:
25-
cls.sim = DeviceManager.Simulator.ensure_available(Settings.Simulators.DEFAULT)
2623

2724
def setUp(self):
2825
TnsTest.setUp(self)
@@ -37,20 +34,28 @@ def tearDownClass(cls):
3734

3835
@timed(300)
3936
def test_001_tns_run_android(self):
40-
result = Tns.run_android(app_name=self.app_name, device=self.emu.id, wait=False)
37+
result = Tns.run_android(app_name=Settings.AppName.DEFAULT, device=self.emu.id, wait=False)
4138

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

47-
# Wait until app is build and installed.
48-
texts = ['Project successfully built', 'Successfully installed']
49-
TnsHelpers.wait_for_log(result.log_file, texts)
44+
# Verify console logs of `tns run` command
45+
plugins = ['nativescript-theme-core', 'tns-core-modules', 'tns-core-modules-widgets']
46+
messages = TnsLogs.run_messages(app_name=Settings.AppName.DEFAULT,
47+
platform=Platform.ANDROID,
48+
run_type=RunType.FIRST_TIME,
49+
plugins=plugins)
50+
TnsLogs.wait_for_log(result.log_file, messages)
51+
52+
# Verify app looks ok
53+
for text in Apps.HELLO_WORLD_JS.texts:
54+
self.emu.wait_for_text(text=text)
5055

5156
@timed(300)
5257
def test_002_tns_run_android_with_justlaunch(self):
53-
result = Tns.run_android(app_name=self.app_name, device=self.emu.id, justlaunch=True, wait=True)
58+
result = Tns.run_android(app_name=Settings.AppName.DEFAULT, device=self.emu.id, justlaunch=True, wait=True)
5459
assert result.complete is True, 'tns run with --justlauch and wait=true should wait until command is executed.'
5560
assert result.exit_code == 0, 'tns run should be successful.'
5661
assert 'Successfully synced application' in result.output

data/apps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Apps(object):
5454
SCHEMATICS_SHARED = AppInfo(app_type=AppType.SHARED_NG, app_id=None, size=__shared_size, texts=['Welcome'])
5555
SCHEMATICS_SHARED_SAMPLE = AppInfo(app_type=AppType.SHARED_NG, app_id=None, size=__shared_size, texts=['Barcelona'])
5656
SCHEMATICS_NS = AppInfo(app_type=AppType.NG, app_id=None, size=__ns_only_size, texts=['Tap the button'])
57-
HELLO_WORLD_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=None)
58-
HELLO_WORLD_TS = AppInfo(app_type=AppType.TS, app_id=None, size=None, texts=None)
57+
HELLO_WORLD_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=['Tap the button'])
58+
HELLO_WORLD_TS = AppInfo(app_type=AppType.TS, app_id=None, size=None, texts=['Tap the button'])
5959
HELLO_WORLD_NG = AppInfo(app_type=AppType.NG, app_id=None, size=None, texts=None)
6060
MIN_JS = AppInfo(app_type=AppType.JS, app_id=None, size=None, texts=None)

data/issues/liveSyncJS/app.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
In NativeScript, the app.js file is the entry point to your application.
3+
You can use this file to perform app-level initialization, but the primary
4+
purpose of the file is to pass control to the app’s first module.
5+
*/
6+
7+
var application = require("tns-core-modules/application");
8+
application.on(application.launchEvent, () => {
9+
console.log("application started");
10+
});
11+
application.run({ moduleName: "app-root" });
12+
13+
/*
14+
Do not place any code after the application has been started as it will not
15+
be executed on iOS.
16+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component, OnInit } from "@angular/core";
2+
3+
import { Item } from "./item";
4+
import { ItemService } from "./item.service";
5+
6+
@Component({
7+
selector: "ns-items",
8+
moduleId: module.id,
9+
templateUrl: "./items.component.html",
10+
})
11+
export class ItemsComponent implements OnInit {
12+
items: Item[];
13+
14+
// This pattern makes use of Angular’s dependency injection implementation to inject an instance of the ItemService service into this class.
15+
// Angular knows about this service because it is included in your app’s main NgModule, defined in app.module.ts.
16+
constructor(private itemService: ItemService) { }
17+
18+
ngOnInit(): void {
19+
console.log("items component on init");
20+
this.items = this.itemService.getItems();
21+
}
22+
}

data/issues/liveSyncNG/main.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// this import should be first in order to load some required settings (like globals and reflect-metadata)
2+
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
3+
4+
import { AppModule } from "./app/app.module";
5+
6+
import * as application from "tns-core-modules/application";
7+
application.on(application.launchEvent, () => {
8+
console.log("applications started");
9+
});
10+
// A traditional NativeScript application starts by initializing global objects, setting up global CSS rules, creating, and navigating to the main page.
11+
// Angular applications need to take care of their own initialization: modules, components, directives, routes, DI providers.
12+
// A NativeScript Angular app needs to make both paradigms work together, so we provide a wrapper platform object, platformNativeScriptDynamic,
13+
// that sets up a NativeScript application and can bootstrap the Angular framework.
14+
platformNativeScriptDynamic().bootstrapModule(AppModule);

data/issues/liveSyncTS/app.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
In NativeScript, the app.ts file is the entry point to your application.
3+
You can use this file to perform app-level initialization, but the primary
4+
purpose of the file is to pass control to the app’s first module.
5+
*/
6+
7+
import * as application from "tns-core-modules/application";
8+
application.on(application.launchEvent, () => {
9+
console.log("application started");
10+
})
11+
12+
application.run({ moduleName: "app-root" });
13+
14+
/*
15+
Do not place any code after the application has been started as it will not
16+
be executed on iOS.
17+
*/

data/sync/hello_world_js.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from core.utils.wait import Wait
1111
from data.changes import Changes, Sync
1212
from data.const import Colors
13+
from products.nativescript.run_type import RunType
1314
from products.nativescript.tns import Tns
15+
from products.nativescript.tns_logs import TnsLogs
1416

1517

1618
def sync_hello_world_js(app_name, platform, device, bundle=False, hmr=False, uglify=False, aot=False,
@@ -56,6 +58,10 @@ def __sync_hello_world_js_ts(app_type, app_name, platform, device,
5658
bundle=bundle, hmr=hmr, uglify=uglify, aot=aot, snapshot=snapshot)
5759
__verify_snapshot_skipped(snapshot, result)
5860

61+
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
62+
hmr=hmr)
63+
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
64+
5965
# Verify it looks properly
6066
device.wait_for_text(text=js_change.old_text, timeout=120, retry_delay=5)
6167
device.wait_for_text(text=xml_change.old_text)
@@ -67,31 +73,49 @@ def __sync_hello_world_js_ts(app_type, app_name, platform, device,
6773
# Edit JS file and verify changes are applied
6874
Sync.replace(app_name=app_name, change_set=js_change)
6975
device.wait_for_text(text=js_change.new_text)
76+
strings = TnsLogs.run_messages(app_name=app_name, platform=platform, run_type=RunType.FULL, bundle=bundle,
77+
hmr=hmr, file_name='main-view-model.js')
78+
TnsLogs.wait_for_log(log_file=result.log_file, string_list=strings)
7079

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

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

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

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

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

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

0 commit comments

Comments
 (0)