angular-protractor: conflict with JQuery #2734

Closed
turp opened this Issue Aug 28, 2014 · 51 comments

Projects

None yet
@turp
turp commented Aug 28, 2014

I'm seeing the following conflict when using Protractor with JQuery.

Subsequent variable declarations must have the same type.  
Variable '$' must be of type 'cssSelectorHelper', but here has type 'JQueryStatic'.
Web\Scripts\typings\jquery\jquery.d.ts   3936

I tried to uninstall JQuery, but 'angularjs.TypeScript.DefinitelyTyped 2.0.6 depend(s) on it.

I'm using the following version:

<package id="angularjs.TypeScript.DefinitelyTyped" version="2.0.6" targetFramework="net45" /
<package id="angular-protractor.TypeScript.DefinitelyTyped" version="0.0.4" targetFramework="net45" />
<package id="jquery.TypeScript.DefinitelyTyped" version="1.3.8" targetFramework="net45" />

Thanks
Jay

@awerlang
Contributor

+1

It seems that it is not possible to reference both files in the same project, even if they aren't used in the same

@turp You could handle this by moving your e2e tests to a new project.

@brian428
Contributor

Yeah, rather annoying even though it's not the fault of either TSD. Given that both libraries set up a global $ function, I'm not even sure you can load both underlying JS libraries at the same time?

@tiparkki

+1

@jt000 jt000 referenced this issue in Microsoft/TypeScript Dec 16, 2014
Closed

How to have a conditional ambient type? #1511

@jt000
Contributor
jt000 commented Dec 16, 2014

I had created the above issue in typescript, but as I was thinking about it I came to the conclusion that this is likely an issue with how TSD is creating the tsd.d.ts file. Since we shouldn't be using both JQuery and angular-protractor in the same typescript file, then we should have a dedicated set of references for each scenario...

However, not sure how this would be done specifically... Maybe something like having a "dev" version of a tsd.d.ts for tests? (i.e. tsd install --save-dev that would save to "tsd.dev.d.ts"?)

@brian428
Contributor

I set up two TSDs, one used by my main app, and one to reference from functional test code. Obviously, the protractor d.ts isn't part of my main app TSD.

@jt000
Contributor
jt000 commented Dec 16, 2014

I gave that a try & it didn't work for me. Maybe I have something different in my project, but by simply including the d.ts (regardless of the in the ts files) causes the build issue. Do you have a single VS project for both your unit\functional test code & your app?

@jt000
Contributor
jt000 commented Dec 16, 2014

After playing with this for a couple hours now, it really seems like there's something off with the typescript compiler that might be compounding this issue... If I have 2 ts files in my project, 1 references angular-protractor and the other ts file references jquery, then I get "TS2134: Build: Subsequent variable declarations...". Since the ts are independent of each other and don't reference both angular-protractor & jquery at the same time, then this build issue should never be hit.

I'm going to create a simple github project to demonstrate & file an issue against typescript (again).

@brian428
Contributor

I don't use Visual Studio so I'm not sure if that's part of the issue or not. I use IDEA to code, and Gulp to watch the file system, compile, and produce the build artifacts.

@jt000
Contributor
jt000 commented Dec 17, 2014

when Gulp compiles, does it call TSC per file or once for all files? For example,

tsc a.ts b.ts c.d.ts

or

tsc a.ts
tsc b.ts

Visual Studio builds the first way, which I think is why I'm seeing the issue & why having multiple tsd.d.ts files isn't working for me. I would guess Gulp does it the 2nd way (though, i've never used Gulp, so this is just a guess).

@brian428
Contributor

I'm actually not sure. I have it compiling and aggregating the JS into a single file, along with a source map for easier debugging, but you can also have it compile out to individual JS files. It can also do incremental compilation for updates, which speeds things up. So it almost seems like it does both, but that's really just a guess. (If it helps, you can see what it is using here: https://github.com/ivogabe/gulp-typescript/tree/master/typescript).

@StanleyGoldman
Contributor

I am struggling with this issue as well

@bgever
bgever commented Feb 12, 2015

+1

@ShiraazMoollatjie

+1

I ended up using the workaround suggested by @awerlang.

@jasond-s
Contributor

+1 This is most annoying.

@brian428
Contributor

I'm not really sure what's not sinking in here. Angular depends on jQuery, which defines a $() function. The Protractor JS library also defines a $() function (because this is what the underlying Webdriver API is). The jQuery and Protractor TSD's can only match the API declared by the original JS libraries. If you include both the Angular and Protractor TSDs, you're going to have a conflict. There's nothing the author of the Protractor TSD can do about this.

The only possible option would be to create a Protractor TSD that omits $() from the definition. But then, anyone using the TSD would be forced to use something like element(by.css(selector)) everywhere, instead of $(). And I doubt that anyone would be happy with that.

Since I don't think there's any reason for Protractor code to depend on Angular or jQuery anyway, the only viable solution seems to be just not referencing the Angular TSD within the Protractor project/code. That probably means using a separate project, or at least separate TSD listings.

@jt000
Contributor
jt000 commented Feb 17, 2015

If you're using Visual Studio to build & have both protractor/angular in the same project, then please put your "+1" in Microsoft/TypeScript#1516 to let them know I'm not the only one seeing this issue

@jasond-s
Contributor

This is the first google hit for the issue. I knew at the time it was VS's fault but the red mis, it made me do it.

@awerlang
Contributor

For those who want main app and tests on the same VS project, refer to PR #3528. Get it and see if anything's broken at your side. It must fix this issue.

@brp-nylin
Contributor

+1

This is really annoying indeed. I wonder why protractor used $ in the first place, wasn't jQuery well established when Protractor was developed? I can't get my e2e tests compiled with TS and TSLint and don't seem to find a way of fixing this.

Has anyone found a good workaround? I was thinking about settings up two tsd folders, but since both my app and my e2e tests needs type definitions for angular this wouldn't help anyway.

I understand the implications of this problem, and that it doesn't really help anyone to

@brian428
Contributor
brian428 commented May 8, 2015

Protractor is just a wrapper for Selenium/Webdriver, which uses $ and $$ extensively.

However, I'm not sure why your e2e tests project would actually need the Angular or JQuery definitions?

@vvakame vvakame referenced this issue in Microsoft/TypeScript May 13, 2015
Closed

Change project option resolution #3102

@stites
stites commented May 22, 2015

+1 @brian428

Keep in mind that angular-mocks also has a reference to angular.d.ts — so you may have to further split your unit test definition files from your e2e ones.

@chaosmail
Contributor

Hi guys,

I sent a PR to DefinitelyTyped #4844 to allow embedding of a noConflict version of jQuery. This would be an acceptable solution for me. Please feel free to add your comments and thoughts to the proposed workaround.

Until this PR is merged, I use the following tsd.json configuration (I am using a fork of DefinitelyTyped and replaced the jQuery lib). A tsd reinstall -o should override the current jQuery version.

{
  "version": "v4",
  "repo": "chaosmail/DefinitelyTyped",
  "ref": "master",
  "path": "typings",
  "bundle": "typings/tsd.d.ts",
  "installed": {
    "angularjs/angular.d.ts": {
      "commit": "220ada3f90a7b9e769593650e6aba824bf2f085a"
    },
    "jquery/jquery.d.ts": {
      "commit": "705b4cc80bced7c0cc95575741113667d210602f"
    },
    "angular-protractor/angular-protractor.d.ts": {
      "commit": "2fe8a6fda29c3340a5e5672b1809a84c88729a30"
    },
    "selenium-webdriver/selenium-webdriver.d.ts": {
      "commit": "2fe8a6fda29c3340a5e5672b1809a84c88729a30"
    }
  }
}

Hope this helps someone.

Edit: It didn't work as expected, because version names are appended in the *.d.ts file. At the moment my repo contains a noConflict version of jQuery.

Best.
Christoph

@basarat
Member
basarat commented Jul 7, 2015

Here's what I did for converting the official AngularSeed project for TypeScript : https://github.com/Microsoft/TypeScriptSamples/blob/master/angular1/CONVERSION.md

The final project : https://github.com/Microsoft/TypeScriptSamples/tree/master/angular1

@serhiisol
Contributor

It won't work if your tests will include functionality, which depends on jQuery.
Lets say you need to test directive's controller or something else and this directive requires jQuery.

@awerlang
Contributor

@SergeySolonko to test controller's you use karma, not protractor. A unit test is what you need, while protractor offers integration tests.

@serhiisol
Contributor

@awerlang you're right. But in this case unit tests also use jasmine and maybe another libraries for testing. And in this case if you'll create one typings.d.ts file and include it for all types of testings - you'll get this error. And in this case you'll need to create 3 typings.d.ts files:

typings.d.ts - for you app sources
typings.tests.unit.d.ts - for your unit tests
typings.tests.e2e.d.ts - for your e2e tests

Difference between them will be in these files:

/// <reference path="../typings/angular-protractor/angular-protractor.d.ts" />
/// <reference path="../typings/selenium-webdriver/selenium-webdriver.d.ts" />

Rest of the references should be the same.
Right?

P.S. if you will setup grunt/gulp task to compile TS sources, you need to exclude test files. In other case, if you'll compile all sources - you'll get this error.

@brian428
Contributor

Correct. I use separate TSDs, and separate gulp tasks to compile source vs. test code.

@xFrigginx

+1

@mirikle
mirikle commented Jul 12, 2016

+1

@AloeDream

+1

@AloeDream AloeDream referenced this issue in mgechev/angular-seed Jul 16, 2016
Closed

Typings conflict (angular-protractor vs jquery) #1126

@flibbertigibbet flibbertigibbet referenced this issue in azavea/climate-change-lab Aug 24, 2016
Closed

Add globals to webpack build to fix linter errors #8

@tylerjvick

+1

@CloudNiner CloudNiner added a commit to azavea/climate-change-lab that referenced this issue Aug 31, 2016
@CloudNiner CloudNiner Add jquery typings to project
Remove protractor typings
As detailed in this issue,
DefinitelyTyped/DefinitelyTyped#2734,
the protractor typings are incompatible with jQuery. The best
workaround suggested is to move integration tests via protractor
and selenium to a different project. Since we will likely not
worry about integration tests in this project, I just removed
the protractor typings.
61b73cd
@CloudNiner CloudNiner added a commit to azavea/climate-change-lab that referenced this issue Aug 31, 2016
@CloudNiner CloudNiner Add jquery typings to project
Remove protractor typings
As detailed in this issue,
DefinitelyTyped/DefinitelyTyped#2734,
the protractor typings are incompatible with jQuery. The best
workaround suggested is to move integration tests via protractor
and selenium to a different project. Since we will likely not
worry about integration tests in this project, I just removed
the protractor typings.
4ca2af2
@hirako2000

+1

@mchurichi

+1

@jakeNiemiec

+1

@Ch0bits
Contributor
Ch0bits commented Sep 12, 2016

+1

@robsonrosa

+1

@jakeNiemiec
jakeNiemiec commented Sep 14, 2016 edited

We should really make a new issue, this one is from 2014. This issue is also for the first angular/protractor and I am sure all of us are here for angular2.

@robsonrosa

angular1 here :)

@sergiomichels

@jakeNiemiec Nope, using AngularJS 1.x here. We're just trying to minimize the migration effort in the future.

@icegnome

+1

@ihrimech
ihrimech commented Oct 3, 2016

+1

@smitalm
smitalm commented Oct 4, 2016

Is there any way i can use jquery and protractor typings in the same project, without modifying typings sources and without getting this error? After all this time, there must be a way :(

@the-map
the-map commented Oct 5, 2016

+1

This is really annoying. Introduction of "Types" to Javascript is supposed to increase productivity! I am JS pro & I have been working on it since month and I still keep on getting such annoying issues which diverts your focus from actual functionality! Sadly, I don't see productivity in action with Types!

@sky-coding

+1
Really, 2 years?

@Andrey-Pavlov

Fix it please!

@jakeNiemiec

There is ~1000 open issues, no one is going to find this (2 years and counting).

Looking at the history of contributors, @cnishina may be able to help (his profile tagline: Mission: typescript protractor tests)

@vvakame is also a recent contributor (seemingly related issue here: Microsoft/TypeScript#3102 (comment).

@cnishina
Contributor
cnishina commented Oct 14, 2016 edited

Hi everyone. I've had this issue bookmarked for a very long time and have been meaning to respond.

Since angular-protractor is built off an older version of Protractor, we decided to not maintain this.

Protractor has been slowly migrating JavaScript files to TypeScript. If you are using the latest version of Protractor (v 4.0.9), it has built in TypeScript support. There is a sample TypeScript project in the Protractor repo as well as in the cookbook. Just a quick note: TypeScript support is still experimental, check the changelog for any potential breaking changes.

So to not have a jQuery conflict, you must set noGlobals to true. (See config file). This will ensure that protractor publishes a single global object called 'protractor'.

import {$} from 'protractor';

The import actually uses the global protractor.$ and does not use global $ that jQuery uses.

So let's say you are using $ for jQuery. The above typing doesn't work if you are importing $ from Protractor... so maybe you want to do the following:

import {$ as Protractor$} from 'protractor';
@cnishina
Contributor

Hopefully the above response is enough to close this issue. 🎉

Below is more details about "fixing" angular-protractor and probably why it might not be ideal:

API mismatch

Since Protractor version 1.5, some of the APIs have changed causing a version mismatch for the ambient typings. This is probably the most important reason why Protractor now supports TypeScript.

Below is the proposed fix; however, making this change will ultimately break tests for users that do not have an ambient typing problem with jQuery. This might be a good reason to use Protractor 4.0.9+.

The fix for Protractor 3.2+

For users that are using Protractor 3.2+ and < 4, using the noGlobals flag would ensure that there are no conflicts at the global namespace for $. The fix would be to remove the declare var $ as well as other global variables completely from angular-protractor.d.ts. This would require users to set up their own Protractor variables.

import {Protractor} from 'protractor';

let protractor: Protractor = (global as any)['protractor'];
let $ = protractor.$; 

The fix for Protractor < 3.2

Again, the fix would be to remove the declare var $ and other global variables as stated above and would also require users to set up their own Protractor variables (also shown above). However, if you are using jQuery in your Protractor file, there still is a global namespace problem with Protractor's $ and jQuery's $.

@jakeNiemiec

@cnishina Thanks for following up!

@cnishina
Contributor

@andy-ms This should be closed since angular-protractor does not exist.

@andy-ms andy-ms closed this Jan 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment