Angular e2e testing ng-show - validation

I use ng-pattern for validation, use ng-show to display the error message. This works fine on browser, but how do I code it in e2e to test if the error message shows up?
Here is my HTML:
<input type="text" ng-model="test.pname" name="pname" ng-maxlength="30" ng-pattern="/^[a-zA-Z0-9 ]*$/"/>
<span class="custom-error" id="pnameValidate" ng-show="addProviderForm.pname.$error.pattern">
PName can be Alpha-Numeric up to 30 characters – spaces allowed, but no special characters</span>
Here is my e2e script:
input('test.pname').enter('cakes`');
expect(element('#pnameValidate:visible').text()).toMatch(/up to 30 characters/);
input('test.pname').enter('cakes are good');
expect(element('#pnameValidate:visible').text()).toBe('');
Here is the result from test runner:
expected "" but was "\n PName can be Alpha-Numeric up to 30 characters – spaces allowed, but no special characters"
it seems in the test runner the #pnameValidate always shows no matter what I specify in e2e.

Have you tried adding wait time to the test to allow the UI to catch up with the script?
input('test.pname').enter('cakes`');
expect(element('#pnameValidate:visible').count()).toBe(1);
expect(element('#pnameValidate:visible').text()).toMatch(/up to 30 characters/);
input('test.pname').enter('cakes are good');
setTimeout(function() {
expect(element('#pnameValidate:visible').count()).toBe(0);
expect(element('#pnameValidate:visible').text()).toBe('');
}, 500);

Your problem is ".enter"
change it to ".sendKeys"

Related

How to test if an alert message is showing what I wanted it to show using Cypress?

I have password reset page I'd like to perform some tests on. If my current password won't match with my typed current password area it shows a "Password don't match" alert. Here is my alert:
<p-message *ngIf="error" severity="error" id="alert-danger" class="alert alert-danger" text="{{'password.messages.error' | translate}}" >
<ng-template pTemplate>
<div jhiTranslate="password.messages.error" ></div>
</ng-template>
</p-message>
What I've tried so far:
cy.get('[severity="error"] > .p-inline-message > .p-inline-message-text')
.should("have.text","password.messages.error")
But I get an error in cypress saying "expected password.messages.error but the text was Passwords don't match!. Which is understandable it takes directly whatever text was inside my element. Then I've tried:
cy.get('[severity="error"] > .p-inline-message > .p-inline-message-text')
.invoke('attr','jhiTranslate')
.should('eq','password.messages.error')
this gives me "expected undefined to equal password.messages.error"
What I'm doing wrong and what else should I try here?
Just change the text Cypress is checking,
cy.get('[severity="error"] > .p-inline-message > .p-inline-message-text')
.should("have.text", "Passwords don't match!")
The HTML you show above is the source code, but AngularJS has looked up the variable password.messages.error and output the string contained in that variable.
It then removes jhiTranslate from the element, so you cannot test it at runtime (in the browser).
You can see what the runtime HTML is by right-clicking on an element and inspecting it in the dev-tools.
You can do something like:
cy.get('p-message#alert-danger').within(() => {
cy.get('div').should('have.attr', 'jhiTranslate', 'password.messages.error')
})

Cypress - first test randomly fails with "Invalid or unexpected token"

Recently switched to using Cypress parallel for our Angular project in our pipeline. We run on a Codebuild on AWS and run 5 threads of the Cypress runner. About a quarter of the time, the first test on one of the threads fails with this error:
An uncaught error was detected outside of a test
Invalid or unexpected token
This error originated from your test code, not from Cypress.
When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
Cypress could not associate this error to any specific test. We dynamically generated a new test to display this failure.
Tried many things to try to fix this, including setting modifyObtrusiveCode to false, chromeWebSecurity to false, upgrading Cypress. We are already catching uncaught exceptions so that doesn't seem like it should be the issue. I turned on some extra logs for this and here is the output
[3] 2020-03-06T19:57:20.369Z cypress:server:project onMocha start
[3] 2020-03-06T19:57:20.369Z cypress:server:reporter got mocha event 'start' with args: [ { start: '2020-03-06T19:57:20.366Z' } ]
[3] 2020-03-06T19:57:20.374Z cypress:server:project onMocha suite
[3] 2020-03-06T19:57:20.374Z cypress:server:reporter got mocha event 'suite' with args: [ { id: 'r1', title: '', root: true, type: 'suite', file: 'cypress/integration/ci-tests/content-acquisition/channels/channel-manual-upload-run-acquired-items-tab.spec.ts' } ]
[3]
[3] 2020-03-06T19:57:20.390Z cypress:server:project onMocha test
[3] 2020-03-06T19:57:20.391Z cypress:server:reporter got mocha event 'test' with args: [ { id: 'r2', title: 'An uncaught error was detected outside of a test', body: 'function throwErr() {\n throw err;\n }', type: 'test' } ]
[3] 2020-03-06T19:57:20.555Z cypress:server:reporter got mocha event 'fail' with args: [ { id: 'r2', title: 'An uncaught error was detected outside of a test', err: { message: 'Unexpected end of input\n' + '\n' + 'This error originated from your test code, not from Cypress.\n' + '\n' + 'When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.\n' + '\n' + 'Cypress could not associate this error to any specific test.\n' + '\n' + 'We dynamically generated a new test to display this failure.', name: 'Uncaught SyntaxError', stack: 'Uncaught SyntaxError: Unexpected end of input\n' + '\n' + 'This error originated from your test code, not from Cypress.\n' + '\n' + 'When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.\n' + '\n' + 'Cypress could not associate this error to any specific test.\n' + '\n' + 'We dynamically generated a new test to display this failure.' }, state: 'failed', body: 'function throwErr() {\n throw err;\n }', type: 'test', duration: 179, wallClockStartedAt: '2020-03-06T19:57:20.374Z', timings: { lifecycle: 26, test: [Object] } } ]
I couldn't really make anything of these errors, but maybe someone else can. I'm kind of out of ideas on what to try (I've tried more things today than I've listed but can't recall them all). Any ideas?
as setting modifyObtrusiveCode to false didn't help you as the folks in https://github.com/cypress-io/cypress/issues/6132 .. I can give my debug procedure when I encountered a similar flakey "unexpected .." error with Cypress:
cypress run has a burn= param, able to repeatedly run. Enable .har output recording for those runs with the cypress-har-generator plugin.
When you have two groups of successful and failing example .har files for the same request, open them in a Browser to compare if anything stands out.
I used diff + jq queries on the .har files to compare between the groups content per request path, but already opening a failing .har in the browser inspector network tab showed a 30s processing time for a .js path that was ultimately incomplete, and thus violated js syntax, causing an unexpected end of input error, similar to your "unexpected token".
Interestingly this occured to the same file at the same code line, hinting at a parsing problem in Cypress.
We exchanged that dependency (or specifically - updated it and changed how it was webpacked) and Cypress stopped to hiccup on the ressource, the flakiness disappeared.
My impression is, running parallel threads of Cypress contributes to the problem occuring.

"params" doesn't work in Ruby (Sinatra framework)

I have a simple Sinatra app in which I want to create a form so users can change their number. However, I don't even get as far as changing the number because "params" is not working. Everything is working well. I can see the parameters in the URL but if I print "params" there is nothing but "Echo".
class MyApp < Sinatra::Application
register Sinatra::ActiveRecordExtension
get '/changenumber' do
p params
p params[:mynumber]
p "Echo"
end
end
And a Form:
<form action="/changenumber" method="GET">
Phone: <input type="text" name="mynumber" value="<%= user.number %>">
<input type="submit" value="Change Number">
</form>
As vu-minh-tan pointed out you should probably use Post instead of Get.
I rebuild your example and It works well:
{"mynumber"=>"test"}
"test"
"echo"
IP - - [TIME] "GET /changenumber?mynumber=test HTTP/1.1" 200 4 0.0005
Based on this, I think your problem is that you just lock at the output in your browser. And thats only the last line in your code. You should probably try something like this:
get '/changenumber' do
"Params: #{params} mynumber: #{params[:mynumber]}"
end

Text to HTML conversion without *any* formatting

I want to convert the output of a shell command to HTML, regardless of what the command prints.
I've tried using txt2html and pandoc but the first will not keep lines of hypens, even with the --nounhipenation param, and also formatting tags like < h1 > to some lines.
with txt2html this output:
TEST: SimpleTest
-----------------------------------
All test completed in 1ms
Warning: No asserts run!
All assert(s) passed.
-----------------------------------
becomes:
<h1>TEST: SimpleTest</h1>
<p> All test completed in 1ms<br/>
Warning: No asserts run!<br/>
All assert(s) passed.
</p><hr/>
Notice the missing hypens and the spurious < h1 > < /h1 > and for some reason < hr/ > tags.
I would like it to output something like:
<p>TEST: SimpleTest<br/>
-----------------------------------<br/>
All test completed in 1ms<br/>
Warning: No asserts run!<br/>
All assert(s) passed.
-----------------------------------<br/>
</p>
I have done this before and the following has worked for me.
http://2partsmagic.com/util/text2html.jsp

text_field.set not working in test script but works fine in irb

I'm trying to rename a folder from:
<li class="selected rename" id="labelset-624" folderid="624" foldertype="labelset" permissionlevel="2" labelsetid="624">
<div class="folder-insert-drop ui-droppable"></div>
<div class="clear"></div>
<div class="folder-item droppable hoverable empty ui-droppable">
<div id="mlink-labelset-624" class="folder-menu-link" data-hasfullperm="true" data-subfoldertype="undefined"></div>
<div class="expander"></div>
<div class="folder-name labelset label-set">New Label Set</div>
<div class="target-bar"></div>
<div class="folder-rename">
<input value="New Label Set" id="folder-rename-624" maxlength="100" type="text">
</div>
with watir-webdriver using the following commands:
#b.li(:class, "selected rename").div(:class, "folder-rename").text_field.wait_until_present
#b.li(:class, "selected rename").div(:class, "folder-rename").text_field.set labelsetName
#b.li(:class, "selected rename").div(:class, "folder-rename").text_field.send_keys :return
And it gives me the following error:
Watir::Exception::UnknownObjectException: unable to locate element, using {:class=>"selected rename", :tag_name=>"li"}
When I run my test script (test-unit), I can see the value for labelsetName entered into the text field, but it quickly disappears and reverts to the default value. This causes the send_keys statement to err.
When I enter the same commands into irb, it works perfectly. I tried adding sleeps of up to 15 seconds between steps to no avail. Is there any reason the two would work differently? Any suggestions for fixing this going forward?
Unless you have a compelling reason otherwise, try accessing the <input> tag directly using the id attribute:
b.text_field(:id => "folder-rename-624").set "foo"
b.text_field(:id => "folder-rename-624").send_keys :return
And--if there's an associated submit button--try using that instead of send_keys :return.
EDIT: Unfortunately, I can't reproduce the disappearing text issue. But I'm adding this snippet, which should handle the incrementing id attribute:
tfs = b.text_fields
b.text_field(:id => "#{tfs.last.id}").set "foo"
b.text_field(:id => "#{tfs.last.id}").send_keys :return
Turns out that because I had run the test a number of times, each time creating a new folder, that the folder I was trying to rename got pushed off screen. This is what caused the error.

Resources