c roald
c roald

Reputation: 2004

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

What's going on?

Upvotes: 3

Views: 1172

Answers (2)

Sebastian Brannstrom
Sebastian Brannstrom

Reputation: 890

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.

Upvotes: 2

Braains
Braains

Reputation: 606

As Jonathan Penn said this is a known bug but you can create a header file that imports all the necessary files for your tests, and then import that header file at the beginning of whatever script runs first.

Upvotes: 0

Related Questions