We invested a large amount of time in them recently, and I agree they are terrible to write. We dare not even turn on IE or any other browser, we can't even keep the tests green in Firefox. Really wish we'd used cypress instead as its 100x easier to debug and we're not getting cross-browser benefits anyways.
The underlying architecture is a bad design for heavy javascript apps in my opinion. The roundtrips between the test runner talking to selenium server talking to selenium driver in a browser and back the other way is slow and so much can change on the page in between steps in your tests. Cypress runs your test code in the javascript process of your browser so I believe theres no or minimal roundtrip lag.
We use `waitFor()` for the UI to stabilize but thats been a hard mental model for devs to follow and as a result we have tons of unnecessary waits in the tests which slows them down. Even things like waiting for a loading modal to disappear before trying to interact with the UI is hard since your code:
`waitFor('.loading-modal', false) // wait for it NOT to exist`
may run BEFORE its even appeared, then fail in the next step when you try clicking on a button and the modal is there now. You can't wait for it to appear first to prevent that, as your code may run after its already come and gone too.
Tons of annoyances or strange behavior like chromedriver doesn't support emojis in inputs, ieDriver had select boxes set value broken at one point, setValue('123') on a field actually does something like 'focus, clear, blur, APPEND 123' so blur logic to set a default value of '0' on your field will result in the final value being '0123' in your tests… just the worst.
> You can't wait for it to appear first to prevent that, as your code may run after its already come and gone too.
While valid that's not typical for many sites- what's th e point of a very short lived pop up? and even if it is part of your page, you can skip the "risky" part of the test and verify it otherwise (logs ? side effects ?) or not at all.
A 'saving…' or 'loading…' popup or any type of interaction preventing mask is a common UX pattern in my opinion in javascripts heavy apps.
We didn't care about testing the popup at all, it was just breaking our other tests in the following way.
In our UI you could click a 'save' button, then a 'saving…' popup appears, meanwhile the 'save' button goes away and an 'edit' button appears (behind the popup), and when the response comes back it says 'Saved.' in the ui.
A test for `$('div=Saved.').toExist()` in wdio works, it does a waitFor under the covers and polls the UI until that text appears. It doesn't care if theres a popup shown or not.
However moving on to the next step in the tests, `$('button=Edit').click()` throws an error 'element is not clickable' if the popup is visible when it happens to runs. Doing multi-command steps like 'check if popup is there, if not click' in general doesn't work as theres so much latency between commands. You can inject javascript in to the page that does both checks in the browsers js process as a hacky workaround.
We did upgrade our webdriver library partly to get waitForClickable() which based on the name at least sounded like it handle the above, but there were no volunteers to update the 168 instances where waitForLoader() had spread in the codebase :/
- A Sr. Marketing staff member saw technical deficiencies in the project and pulled a _complete 180°_ literally days before showtime in front of a huge client, successfully.
- Jobs pushed his workers hard.. though the ends justify the means
- The NeXT computer pioneered nearly everything we take for granted today (mouse, networking, Objective C) in a package targeted at the high end consumer. Sound familiar?
Why the mouse? That was a holdover from Steve’s time at Apple, which was famously “borrowed” from Xerox PARC. Unless next did something special with the mouse that I’m unaware of.
"borrowed" - Apple paid Xerox in stock to have access to their technologies.
Jobs said later that he took away the GUI and the mouse, when he really should have taken away the networking and Smalltalk. That's why NeXT used BSD under the hood and Objective-C as its development environment.
Huh I didn’t know about the stock angle. Apparently it was a purchase agreement since they were pre-IPO, not a giveaway. So he got some pre-ipo financing and a look at great research tech. Very cool deal, thanks for the pointer.
Hardly awful. It was message dispatch object oriented programming. It allowed development of what was essentially the Mac OS X operating system and applications, in the early 1990s. Software that ran on a 25Mhz Motorola 68040. Years before Windows 95, and far more advanced and cohesive and productive than any other desktop computing platform. HTTP and web browsing was invented on a NeXT computer.
I think the single quotes are correct, and are whats in my history. I think they're arguments to the zmv program, which itself does the expansion and $1 substitutions. Otherwise I think that $1 would be substituted once when you run it instead of for each file.
I've used zmv to also reorganize the directory structure of files too, something that seems easier to do with its glob/variable replace syntax.
Nice to have a cross platform option for usage in scripts though.
I'd agree that angular 2 was a letdown. Seems like most people are like me and like typescript, the cli, and a better router, but those could have been incrementally added instead of starting from scratch.
It still boggles my mind thinking about the massive amount of effort google's large team spent on ng2, library authors spend porting ng-bootstrap, plus every app that will be rewritten, plus the interim confusion of having 2 versions of libraries, documentation pages, etc. For improvements in some areas, more complexity in others. And I think to the point of the article, it feels far behind react in a lot of advanced development features as it is still trying to get a solid footing. Just saving a file and waiting a few seconds for a full page reload is much worse than the gulp then webpack browserupdate system I setup for ng1 apps, and the cli is not _that_ much better than a custom gulp task I setup to generate new components and services in ng1.
My theory is the primary motivation for ng2 came from the angular team not wanting to maintain a js and dart version of the library, so they wanted to move it to a single codebase that could compile from nativescript/typescript to both, and it was an easy sell to all the people who identify in the angular tribe.
Some specific things I don't like in ng2:
- Too many ways to do forms. Template driven vs reactive, with some things like mdAutocomplete I could only get working w/ reactive. You can do [ngModel] + name attribute, [ngModel]="name", [(ngModel)], formControl, formControlName. Little things like adding `Validators.required` isn't picked up by the view, so you have to specify required there too to get the little (*) asterisk in the view for mdInput
- Testing got much harder to do, with mocking every dependency. Just when ng1 made frontend unit testing pretty painless to do, it feels like a step back.
- The DI system in general feels like waaay too much complexity for the much smaller benefits it brings now that `import`s are available. I was reading the docs to try to figure out an equivalent to a factory function and I realized even if I could figure it out, another developer or myself in 6 months would not understand it. Mocking imports for testing would be good enough, I think.
- Unless you plan to be an "ng2 developer", dipping into the 100+ ;) rxJS observable methods is a good way to confuse your teammates or future self. Have fun remembering what mergeMapTo vs switchMap vs forkJoin do. Observables are cool, but imo another case of too much complexity and too many ways to do things for the benefits. I haven't seen good guidelines of at which point in your app do you transition from observables (returned from http request) to plain objects - should you pass observables down through components for things that can change, or rely on the component seeing its input property changed? Should I implement a snapshot property on my objects that can change, similar to how they do routes? It is silly to me an http request response is modeled as an unending sequence of events, instead of a promise. The only benefits I see like being able to specify `retry(3)` could be implemented as an option in your api service that wraps http, and would probably be more consistent that way.
- A lot of small things are gone, like a capitalize pipe, ngFor iterating over objects. A little slower when getting started on an app when you have to add them yourself. They got rid of things like http interceptors and route resolves, and are adding them back in now after people complain. Even stuff like adding a query param to a url required a bad java-like api and multiple lines of code. They improved that since, but why start w/ a step back from ng1?
- Speak of route resolves, they have gone from a simple 1 liner in the route definition to being a 10 line standalone service, which you have to import and add to your providers array.
- Hasn't been an issue for a while, but having your global ng-cli which housed the webpack and typescript config(?) go out of sync w/ your local version, and your angular/core version, was a really confusing and painful upgrade.
- I like typescript, but it does have strange errors where it seems to have an older version of a file cached and you need to restart the server to fix it. Seems to happen more when importing a class that isn't @Injectable()?
- It is slower. My livereloading browsersync ng1 apps were faster and more fun to work on.
- It is a huge pain to rename things or reorganize your files. VSCode was rename symbol which is nice, but to stay consistent when renaming a component you need to rename: each of the 4 files+directory, all the imports, the `selector` and all tag references to it across the app, the `.my-component` css classes. I do a lot less refactoring of component names or directory structure in ng2 than a glob import style ng1 app, where you don't need to manually requiring everything.