cancel
Showing results for 
Search instead for 
Did you mean: 

How to import a javascript class and extend it in another script unit

SOLVED
Occasional Contributor

How to import a javascript class and extend it in another script unit

Hi I am trying to use two Javascript projects - and export a class defined in one to be extended (inherited) in another.

The example here https://community.smartbear.com/t5/TestComplete-General-Discussions/how-to-import-a-javascript-class...

shows how to use require and create an instance of the class.

However, I would like to inherit the class (ES6) and define or override the methods. I was able to do this using prototype based inheritance (ES3). But unable to do this using ES6 terms.

 

The "import" keyword usage shows syntax error "Unexpected token import". If I use require, then I cannot actually use it with extends e.g. 

(Note that I have shared the Parent.js into the project)

 

//In Parent.js

class ParentApp { constructor(x)  { this.name = x; } } module.exports = { ParentApp: ParentApp } //In Child.js var parent = require("Parent") class Child extends parent.ParentApp { constructor(y, z) { super(y);   this.age = z; } }

Here the "parent.Parent" is not working. And I can't use import keyword.

(Note that sometimes having the script name same as class name seems to cause issues and that's why I use Parent and ParentApp to differentiate)

 

So how do I do this? Is ES6 fully suppported in Test Complete 14?

 

1 ACCEPTED SOLUTION

Accepted Solutions
Occasional Contributor

Re: How to import a javascript class and extend it in another script unit

Hi Robert,

 

Thanks for the prompt response. I did help to reconsider what I was doing because the code I shared with you was OK. But I realised something - the issue was not due to these being in different projects - in fact I had shared the Parent.js into the project containing the Child.js. It was because of circular references. Though the TestComplete documentation says Javascript supports circular references, there is catch here:

 

My example question did not mention the full context - here's the code that I had issues with:

PARENT.JS

 

// In Parent.js - In Project 1, but shared into Project 2 using Add Existing Item...
var child = require("Child")

class ParentApp {
  constructor(x)  {
    this.name = x;
  }
}

function initializeGlobal()
{
  var childObj = new child.ChildClass("Me", 3);
}

module.exports = {ParentClass: ParentApp}

 

 

CHILD.JS

 

// In Child.js - in Project 2 - also shared into Project 1
var parent = require("Parent")

class ChildApp extends parent.ParentClass {
  constructor(y, z) {
    super(y);
    this.age = z;
  }
}

function test() {
    var myChild = new ChildApp('Bill', 25);
    Log.Message(myChild.age);
}

module.exports = { ChildClass: ChildApp }

What was happening was that in Parent.js when the first .... var child = require("Child").... was called, the require tried to load Child.JS - and in this was trying to execute "class ChildApp extends parent.ParentClass" which threw an error. This was because parent.ParentClass wasn't loaded yet. If I removed the extends all was well.

 

 

So what I did was to refactor the code so that the function "initializeGlobal()" was in another common script that avoided the circular referencing. It seems circular referencing fails with extends.

 

SAMPLE WORKING CODE:

INIT.JS

 

// In Init.js, in Project 1
var parent = require("Parent")
var child = require("Child")

function initializeGlobal()
{
  var childObj = new child.ChildClass("Me", 3);
}

PARENT.JS

 

 

// In Parent.js - In Project 1, but shared into Project 2 using Add Existing Item...

class ParentApp {
  constructor(x)  {
    this.name = x;
  }
}

module.exports = {ParentClass: ParentApp}

 

 

CHILD.JS

 

// In Child.js - in Project 2 - also shared into Project 1
var parent = require("Parent")

class ChildApp extends parent.ParentClass {
  constructor(y, z) {
    super(y);
    this.age = z;
  }
}

function test() {
    var myChild = new ChildApp('Bill', 25);
    Log.Message(myChild.age);
}

module.exports = { ChildClass: ChildApp }

 

So it's resolved now. Please try it and let me know if this works.

Sorry for getting back this late - the response is a tad too long if you see. 

And yeah, I did not need the "import" keyword.

 

Thanks for the help. And thanks to Tanya for following-up.

 

Maybe I should accept my own answer as solution, I don't know.

View solution in original post

6 REPLIES 6
Community Hero

Re: How to import a javascript class and extend it in another script unit

I tried the following.  Here's a unit that I have called Parent

 

class ParentApp {
  constructor(x)  {
    this.name = x;
  }
}

module.exports = {ParentClass: ParentApp}

Here's another unit that I have called Child

 

var parent = require("Parent")

class Child extends parent.ParentClass {
  constructor(y, z) {
    super(y);
    this.age = z;
  }
}

function test() {
    var myChild = new Child('Bill', 25);
    Log.Message(myChild.age);
}

When I run the test function, I get written to my test log the value of 25.  So, I'm not 100% certain what issue you're running into since it appears that our code is pretty much copies of each other.

 

Note that, in TestComplete, the require should always contain the unit name doing the import and that the unit must be in the same project.  You mention that you have two different projects.  The Parent.js unit needs to be in the same project as your Child.js unit.  

 

See https://support.smartbear.com/testcomplete/docs/scripting/calling-routines/declared-in-another-unit/... for the specifics of using module.exports within TestComplete.


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Community Hero

Re: How to import a javascript class and extend it in another script unit

As a kind of fun example of what all this looks like in TestComplete, I've attached a little "story".  Put all 5 files in a JavaScript project in TestComplete and run the "battle" function in BridgeOfKhazadum.js.


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Community Manager

Re: How to import a javascript class and extend it in another script unit

Thanks for your help, Robert!

@charleshb, is this what you are looking for? or do you still have a question?

 

---------
Tanya Gorbunova
SmartBear Community Manager

Did my reply answer your question? Give Kudos or Accept it as a Solution to help others. ⬇️⬇️⬇️
Occasional Contributor

Re: How to import a javascript class and extend it in another script unit

Hi Robert,

 

Thanks for the prompt response. I did help to reconsider what I was doing because the code I shared with you was OK. But I realised something - the issue was not due to these being in different projects - in fact I had shared the Parent.js into the project containing the Child.js. It was because of circular references. Though the TestComplete documentation says Javascript supports circular references, there is catch here:

 

My example question did not mention the full context - here's the code that I had issues with:

PARENT.JS

 

// In Parent.js - In Project 1, but shared into Project 2 using Add Existing Item...
var child = require("Child")

class ParentApp {
  constructor(x)  {
    this.name = x;
  }
}

function initializeGlobal()
{
  var childObj = new child.ChildClass("Me", 3);
}

module.exports = {ParentClass: ParentApp}

 

 

CHILD.JS

 

// In Child.js - in Project 2 - also shared into Project 1
var parent = require("Parent")

class ChildApp extends parent.ParentClass {
  constructor(y, z) {
    super(y);
    this.age = z;
  }
}

function test() {
    var myChild = new ChildApp('Bill', 25);
    Log.Message(myChild.age);
}

module.exports = { ChildClass: ChildApp }

What was happening was that in Parent.js when the first .... var child = require("Child").... was called, the require tried to load Child.JS - and in this was trying to execute "class ChildApp extends parent.ParentClass" which threw an error. This was because parent.ParentClass wasn't loaded yet. If I removed the extends all was well.

 

 

So what I did was to refactor the code so that the function "initializeGlobal()" was in another common script that avoided the circular referencing. It seems circular referencing fails with extends.

 

SAMPLE WORKING CODE:

INIT.JS

 

// In Init.js, in Project 1
var parent = require("Parent")
var child = require("Child")

function initializeGlobal()
{
  var childObj = new child.ChildClass("Me", 3);
}

PARENT.JS

 

 

// In Parent.js - In Project 1, but shared into Project 2 using Add Existing Item...

class ParentApp {
  constructor(x)  {
    this.name = x;
  }
}

module.exports = {ParentClass: ParentApp}

 

 

CHILD.JS

 

// In Child.js - in Project 2 - also shared into Project 1
var parent = require("Parent")

class ChildApp extends parent.ParentClass {
  constructor(y, z) {
    super(y);
    this.age = z;
  }
}

function test() {
    var myChild = new ChildApp('Bill', 25);
    Log.Message(myChild.age);
}

module.exports = { ChildClass: ChildApp }

 

So it's resolved now. Please try it and let me know if this works.

Sorry for getting back this late - the response is a tad too long if you see. 

And yeah, I did not need the "import" keyword.

 

Thanks for the help. And thanks to Tanya for following-up.

 

Maybe I should accept my own answer as solution, I don't know.

View solution in original post

Community Hero

Re: How to import a javascript class and extend it in another script unit

Yeah, honestly, I'm not sure how that referencing would work outside of the TC environment anyways.  Good catch, man.  I marked your solution.


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available
Occasional Contributor

Re: How to import a javascript class and extend it in another script unit

Thanks, Robert!

When you find some time if you can validate my solution, I would be quite happy. That's because you are much experienced at using TestComplete and that will give me some confidence.

 

Appreciate your time.

New Here?
Join us and watch the welcome video:
Announcements
Top Kudoed Authors