Using WebdriverIO with Angular to create end-to-end tests in TypeScript that involve importing classes leads to an error stating "Cannot use import statement outside a module."

I am facing an issue while trying to set up a suite of end-to-end tests using wdio. Some of the tests utilize utility classes written in TypeScript.

During the compilation of the test, I encountered the following error:

Spec file(s): D:\TEMP\xx\angular-wdio6-builder-demo\e2e\test\specs\basic.spec.ts                                                                               
 Error:  D:\TEMP\xx\angular-wdio6-builder-demo\e2e\test\specs\basic.spec.ts:1                                                                                  
import {Util} from '../util/util.spec';                                                                                                                        
^^^^^^                                                                                                                                                         
                                                                                                                                                               
SyntaxError: Cannot use import statement outside a module                                                                                                      
    at wrapSafe (internal/modules/cjs/loader.js:1054:16)                                                                                                       
    at Module._compile (internal/modules/cjs/loader.js:1102:27)                                                                                                
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)                                                                                  
    at Module.load (internal/modules/cjs/loader.js:986:32)                                                                                                     
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)                                                                                           
    at Module.require (internal/modules/cjs/loader.js:1026:19)                                                                                                 
    at require (internal/modules/cjs/helpers.js:72:18)                                                                                                         
    at D:\TEMP\xx\angular-wdio6-builder-demo\node_modules\@wdio\jasmine-framework\node_modules\jasmine\lib\jasmine.js:89:5                                     
    at Array.forEach (<anonymous>)                                                                                                                             
    at Jasmine.loadSpecs (D:\TEMP\xx\angular-wdio6-builder-demo\node_modules\@wdio\jasmine-framework\node_modules\jasmine\lib\jasmine.js:88:18)                
[0-0] RUNNING in chrome - D:\TEMP\xx\angular-wdio6-builder-demo\e2e\test\specs\basic.spec.ts      

The above error message is from a version of one of the WebdriverIO Boilerplate Projects. The only modification I made (besides updating chromedriver) was transitioning the sample test to TypeScript and incorporating a utility class.

I have attempted various solutions found online, but none have resolved the issue with executing this basic test. It appears that no babel configuration is being recognized.

You can find the source code at https://github.com/rgansevles/angular-wdio6-builder-demo (cloned from https://github.com/migalons/angular-wdio6-builder-demo)

To replicate the problem, clone my repository and run:

npm install
npm run e2e

If anyone has a solution for enabling the import statement in this particular scenario, your input would be greatly appreciated.

Thank you in advance,

Rob

By the way, here is the content of the failing test file located at e2e/test/specs/basic.spec.ts :

import {Util} from '../util/util.spec';

const util = new Util();

describe('webdriver.io page', () => {
  it('should have the right title', () => {
    browser.url('');
    const title = browser.getTitle();
    expect(title).toEqual(util.browserTitle);
  });

  it('should say app is running', () => {
    browser.url('');
    const message = $('body > app-root > div.content > div.card.highlight-card.card-small > span').getText();
    expect(message).toEqual('angular-wdio6-builder-demo app is running!');
  });
});

Answer №1

I've figured it out. There are several steps to follow:

  • Start by creating a tsconfig.json file within the e2e folder. This file should extend the basic tsconfig.json and include the following changes:
    • "module": "commonjs"
    • "types": ["node", "@wdio/sync", "@wdio/jasmine-framework"]
  • Update the wdio.conf.js file for TypeScript compilation
    • Adjust spec pattern from using .js to .ts
    • Add requires: ['ts-node/register'] to jasmineNodeOpts
  • In the package.json file, make sure to add an environment script for e2e
    • "e2e": "TS_NODE_PROJECT=e2e/tsconfig.json ng e2e"

I have forked the same repository and made these changes here: https://github.com/Michel73/angular-wdio6-builder-demo

One final thing: I encountered compile errors in my VSCode with the basic.spec.ts file because VSCode was defaulting to the basic tsconfig.js. To resolve this, I installed the TypeScript Auto Compiler extension for VSCode.

Answer №2

Have you considered incorporating a babel setup into your test framework in the wdio js file? Here's an example:

Mocha:

mochaOpts: {
         ui: 'bdd',
        require: ['@babel/register', './test/helpers/common.js'],
        // ...
    },

Jasmine:

jasmineNodeOpts: {
        // Jasmine default timeout
        helpers: [require.resolve('@babel/register')],
        // ...
    },

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the benefits of maintaining a property as non-observable instead of observable in knockout.js?

In my TypeScript project utilizing Knockout.js, I have a class with several properties. One of these properties is 'description', which is not directly tied to the DOM but needs to be used in popups triggered by certain mouse events (such as butt ...

What is the best way to determine the property type dynamically in TypeScript based on the value of another property?

I have been working with Polymorphic relationships and currently have the following TypeScript interface defined: interface SubjectA {} interface SubjectB {} interface SubjectC {} enum SubjectType { SubjectA = 'Subject A', SubjectB = 'S ...

I encountered difficulties accessing the native Camera API when working with the most recent version of Ionic

Every time I try to run $ ionic cordova plugin add @ionic-enterprise/camera I encounter the following error message [OK] Integration cordova added! ✔ Creating ./www directory for you - done! > cordova plugin add @ionic-enterprise/camera You have ...

Can an Angular application be developed without the use of the app-root tag in the index.html file?

I'm a newcomer to Angular and I'm trying to wrap my head around how it functions. For example, if I have a component named "login", how can I make Angular render it directly? When I try to replace the app-root tag with app-login in index.html, n ...

Encountering issues with dependencies while updating React results in deployment failure for the React app

Ever since upgrading React to version 18, I've been encountering deployment issues. Despite following the documentation and scouring forums for solutions, I keep running into roadblocks with no success. The errors displayed are as follows: $ npm i np ...

Utilizing a single resolver for both parent and child routes in Angular 2

In my Angular 2.0 (stable version) application, I have a specific entity called project. The details of each project are spread across different sections/routes within the app: project/:id/overview project/:id/documents project/:id/logs and more The API ...

What techniques can be used to determine which exact key was matched by a generic?

I am trying to find a method to deduce a more general string type key from a specific string that can be associated with it. type Foo = { [x: `/tea/${string}/cup`]: void; [x: `/coffee/${string}/time`]: void; [x: `/cake/${string}/tin`]: void; } type ...

Are you ready to dive into the world of running an ASP.NET MVC project with Angular in Visual Studio

Currently, I am working on developing a CRUD application using ASP.NET MVC in Visual Studio with Angular. I am interested in running the entire project solely through VS Code without relying on Visual Studio. Does anyone have a solution for achieving thi ...

Wondering how to leverage TypeScript, Next-redux-wrapper, and getServerSideProps in your project?

Transitioning from JavaScript to TypeScript for my codebase is proving to be quite challenging. // store.ts import { applyMiddleware, createStore, compose, Store } from "redux"; import createSagaMiddleware, { Task } from "redux-saga"; ...

Tips for effectively handling the data received from a webservice when logging into a system

My web service provides me with permissions from my user. The permissions are stored as an array in JSON format. I need to find a way to access and display this data in another function. {"StatusCode":0,"StatusMessage":"Authenticated Successfully", "Token ...

Dynamic autocomplete in Oclif utilizing an HTTP request

Is it feasible for Oclif to support the functionality of making API calls to retrieve values for autocomplete? Consider this scenario: A database stores multiple users information Upon typing show users <Tab> <Tab>, the CLI triggers an API ca ...

React-table fails to show newly updated data

I am facing an issue with my react-table where real-time notifications received from an event-source are not being reflected in the table after data refresh. https://i.stack.imgur.com/q4vLL.png The first screenshot shows the initial data retrieval from th ...

Is the new Angular 2 CLI tool incorporating Systemjs?

Seeking Answers Curious about the absence of systemjs.config.js file when using the new Angular2 CLI setup tool. Is there a way to install a basic version of Angular 2 without relying on the CLI tool available on angular.io? Past Experience In the past, ...

What is the process for assigning a predefined type that has already been declared in the @types/node package?

Is there a way to replace the any type with NetworkInterfaceInfo[] type in this code snippet? Unfortunately, I am unable to import @types/node because of an issue mentioned here: How to fix "@types/node/index.d.ts is not a module"? Here is the o ...

The promise was not handled properly as it was rejected with the message: "The constructor xhr2

Currently, I am working on developing an application using ASPNetCore and Angular 5 with Webpack. However, after upgrading to Angular 5, I encountered the following error: Unhandled Promise rejection: xhr2.XMLHttpRequest is not a constructor ; Zone: <r ...

Two services declared with "providedIn: 'root'" that have identical names

Imagine if there are two distinct services in two separate project categories, both sharing the same name. /app/services/category1/my.service.ts: @Injectable({ providedIn: 'root' }) export class MyService { foo() { return 'foo&apo ...

What is the best way to determine the amount of distinct elements in an array of objects based on a specific object property?

I am working with an array called orders. orders = [ {table_id: 3, food_id: 5}, {table_id: 4, food_id: 2}, {table_id: 1, food_id: 6}, {table_id: 3, food_id: 4}, {table_id: 4, food_id: 6}, ]; I am looking to create a function that can calculate ...

Passing dynamic values to nested components within an ngFor loop in Angular

I'm currently facing an issue with a child component inside a ngFor loop where I need to pass dynamic values. Here is what I have attempted so far, but it doesn't seem to be working as expected <div *ngFor="let item of clientOtherDetails& ...

Issues with displaying validations on an Angular form running Angular 13 are currently being experienced

The warning message is not showing up for the radio button after submitting the form. However, if I click reset once and then submit the form, the warning appears. Please take a look at this video. Additionally, I am facing difficulties in enforcing minimu ...

Tips on how to connect with ngFor

I have been working on an application to display various events, but I am encountering an issue. Whenever I load the webpage, it appears empty and the console throws an error saying 'Can't bind to 'ngForEvent' since it isn't a know ...