Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining #imports in UIAutomation javascript

I'm trying to break up my UIAutomation test scripts into chunks, to make it possible to run them one piece at a time or all together. So I have a structure:

all-tests.js:

#import "tab-dates.js"
#import "tab-temperatures.js"

tab-dates.js:

#import "../../../Libraries/tuneup_js/tuneup.js"
#import "dpl_assertions.js"

var target = UIATarget.localTarget();
var app = target.frontMostApp();

test("Verify date view is shown", function() {
    assertEquals(tabBar.selectedButton().name(), "Date");
});

Both of these live in the same directory, and are imported into an automation trace file that also lives in the same directory.

When I run tab-dates.js directly, everything is fine. tuneup.js is found, path is correct, test passes. But when I try to run all-tests.js, I get:

Script threw an uncaught JavaScript error: Can't find variable: test on line 8 of tab-dates.js

It's not a straight path problem, because if I edit the script to break the path I get a different error that explicitly says 'file not found'.

As far as I can tell, chaining imports is supposed to work -- I mean, this is the entirety of tuneup.js (https://github.com/alexvollmer/tuneup_js):

#import "assertions.js"
#import "lang-ext.js"
#import "uiautomation-ext.js"
#import "screen.js"
#import "test.js"
#import "image_assertion.js"

So I have the weird situation that

  • tab-dates.js imports tuneup.js imports test.js => OK
  • all-tests.js imports tab-dates.js imports tuneup.js imports test.js => NOT OK

What's going on?

like image 883
c roald Avatar asked Aug 14 '26 16:08

c roald


1 Answers

TL;DR the initial script you run is special. To work around this, create an initial script that includes exactly one other script, and then these general rules apply:

  • imports are done in the order they appear in a file
  • a script will first execute, then do its imports
  • imports are done depth first
  • a script imported once will not be re-imported

However, the initial script does not obey these rules.

I spent some time figuring this out by creating four scripts: one.js; two.js; three.js and other.js, where one.js imports two.js; which imports three.js; which imports one.js and they all import other.js. Apart from the import, the scripts log their name, like so:

#import "two.js";
#import "other.js";
UIALogger.logMessage("one.js");

If I then run one.js, the output I get is

2015-03-04 21:21:20 +0000 Default: two.js
2015-03-04 21:21:20 +0000 Default: three.js
2015-03-04 21:21:20 +0000 Default: one.js
2015-03-04 21:21:20 +0000 Default: other.js
2015-03-04 21:21:21 +0000 Default: one.js

Then I created a script called launch.js, that imports one.js and nothing else. When I run this script, the output I get is:

2015-03-04 21:27:59 +0000 Default: one.js
2015-03-04 21:27:59 +0000 Default: two.js
2015-03-04 21:27:59 +0000 Default: three.js
2015-03-04 21:28:00 +0000 Default: other.js
2015-03-04 21:28:00 +0000 Default: launch.js

From this we can deduce that:

  • the initial script called will first do its imports, then execute
  • the initial script will be re-imported and run if imported by other scripts, exactly once
  • imports are done depth first

So use the launch.js strategy to reduce pain in your life.

like image 96
Sebastian Brannstrom Avatar answered Aug 17 '26 06:08

Sebastian Brannstrom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!