Codeception see and dontSee both fail - codeception

I'm using the Selenium2 module for acceptance tests
My acceptance.suite.yml contains
class_name: WebGuy
modules:
enabled: [Selenium2]
config:
Selenium2:
url: 'http://localhost/'
browser: firefox
capabilities:
unexpectedAlertBehaviour: 'accept'
In my test file I've tried both of the following and they both fail
$I->seeElement('.menu .subMenu');
$I->dontSeeElement('.menu .subMenu');
I would expect the dontSee assertion to pass as the sub menu is hidden by default
The error I get is
Guy unexpectedly managed to see element ".menu .subMenu": Failed asserting that an object is empty.
The beginning of my HTML looks like this
<div class="menu">
<div class="subMenu" style="display: none;">
<ul>
<li>Contact</li>
</ul>
</div>
</div>

Try using XPaths:
$I->seeElement("//div[#class='menu']");

I believe this is a bug in Codeception: https://github.com/Codeception/Codeception/issues/617
Edit: Switching to the WebDriver module instead of Selenium seems to have fixed the problem for me.

Is disabled your HTML-code div.menu by display:none;? Perhaps that's the reason.
I think, I have had a similiar problem with the webdriver and the code
$checkHygienePlans = $I->grabMultiple('.js-my-test-block a');
The result $checkHygienePlans was an array with empty string and $I->assertContains('TestSomeThing', $checkHygienePlans); would fail the test.
The reason was, that the wraping block of the element with class js-my-test-block was hidden with CSS display: none;
After I used codeception to untoggle that block, everything worked fine.

Related

Switch IFrame with Codeception using ID

How can I switch to an IFrame with Codeception using ID? Actually I can use the name of the IFrame but not the ID -> Codeception SwitchToIFrame
IFrame Example:
<iframe id="iframeToolbar" src="link" frameborder="0" style="position: fixed; left: 0px; top: 0px; z-index: 998; width: 940px;" scrolling="no" width="100px" height="100%"></iframe>
Codeception Example:
<?php
# switch to iframe
$I->switchToIFrame("another_frame");
# switch to parent page
$I->switchToIFrame();
Is it maybe a Codeception <-> Facebook Webdriver Connection Problem?
EDIT: I reinstalled Codeception, followed the Quick Step Guide. Result - the Problem is still the same: Codeception and the Facebook Webdriver doesn't want to work together. My Codeception Code
acceptance.suite.yml:
actor: AcceptanceTester
modules:
enabled:
- \Helper\Acceptance
- WebDriver:
url: https://xxxxxxxxxxxxxx.com
browser: chrome
window_size: maximize
clear_cookies: true
codeception.yml:
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
extensions:
enabled:
- Codeception\Extension\RunFailed
settings:
colors: true
OS: Windows 10
PHP: 7.1.7
PHPUnit: 6.4.4
Selenium Server: 3.8.1
Codeception: 2.3.7
Chrome: 63.0.3239.108
I had this issue, testing a page with a Google reCaptcha in it ... the reCaptcha is in its own iframe, and since that iframe is generated by 3rd-party code, we have no control over its name attribute (at least when it's first generated).
What I ended up doing was running a javascript snippet which can find the iframe based on other things, and then giving it an id, so that Codeception Webdriver could switch to it:
public function _clickOnCaptcha(AcceptanceTester $I)
{
// give the recaptcha iframe a name so codeception webdriver can switch to it
$recaptcha_frame_name = 'recaptcha-frame';
$I->executeJS("$('.g-recaptcha iframe').attr('name', '$recaptcha_frame_name')");
$I->switchToIFrame($recaptcha_frame_name);
$I->see('not a robot');
$I->seeElement('.rc-anchor');
$I->click(['id' => 'recaptcha-anchor']);
$I->switchToIFrame(); // switch back to main window
}
I did have control over the containing elements, so in this case, it's contained within an element with class g-recaptcha ... so we use jquery to find the iframe inside that element: $('.g-recaptcha iframe'), and then give it a name attribute: .attr('name', '$recaptcha_frame_name').
Then we can use Codeception to switch to it and click the captcha checkbox:
$I->switchToIFrame($recaptcha_frame_name);
$I->click(['id' => 'recaptcha-anchor']);
Then, when we're done, switch back out to the main frame so we can submit our form:
$I->switchToIFrame(); // switch back to main window
NB, I'm using the reCaptcha test keys, as specified here, in the testing environment so that it will never actually ask to solve a captcha.
https://developers.google.com/recaptcha/docs/faq
With the following test keys, you will always get No CAPTCHA and all verification requests will pass.
Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
The reCAPTCHA widget will show a warning message to claim that it's only for testing purposes. Please do not use these keys for your production traffic.
First of all, in your case the problem might be that you're not calling the acceptance tester. You should start your script with this:
<?php
$I = /*am a */ new AcceptanceTester($scenario);
Now to get into an IFrame in Codeception using the WebDriver:
You just have to name the IFrame in a string, using EITHER the ID or the name. Here is an example:
There is a page with the IFrame:
<iframe name = "IFrameByName" id = "IFrameByID" width = "500" height = "300" src = "https://messagetothefish.com"></iframe>
This IFrame contains the string, "No one knows who discovered water" but the parent frame does not. I tested this Cept with PhantomJS and Selenium.
<?php
$I = /*am a */ new AcceptanceTester($scenario);
$I->wantTo('See how Iframes work');
$I->amOnUrl("https://wordpress-bdd.com/codeception-iframe/");
$I->dontSee("No one knows who discovered water");
//Switch by name
$I->switchToIFrame("IFrameByName");
$I->see("No one knows who discovered water");
//switch back to parent
$I->switchToIFrame();
$I->dontSee("No one knows who discovered water");
//Switch by ID
$I->switchToIFrame("IFrameByID");
$I->see("No one knows who discovered water");
$I->dontSee('Lorum Ipsum');
//switch back to parent
$I->switchToIFrame();
$I->dontSee("No one knows who discovered water");

anchor is not redirecting to display inside ng-view, rather reloading with new page

I wrote a simple angular application in a learning purpose. However the controllers are working in my system but not in plunker. But, that is not my concern. My concern is I am unable to see the linked pages inside ng-view. They are rather opening as a new page replacing the home page. Secondly, the expressions are not reflecting their values. Kindly help me out. I have uploaded the codes in plunker.
Link to Plunker
<div ng-controller="RamFirstCtrl">{{name}}</div>
<div ng-include="'navbar-top.html'"></div>
<div style="border:1px solid green; position:relative;" ng-view></div>
Noticed couple thing:
http to https, there is error in console, it might be the reason it doesn't work in plunker
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
you have to use the url define in your router:
ng-href="aboutUS.html" to ng-href="#!/aboutUS"
.when("/aboutUS", {
templateUrl : "aboutUS.html"
})
<div>
<a ng-href="#!/aboutUS">
AboutUs
</a>
</div>
Note:#! will be added to url by angular router by default

How to do Protractor Testing for ui-view or ng-if?

I am trying to use protractor testing for my website. When I run the test, Firefox displays "Welcome home soldier" which is the part from ng-view="admin" (correct view) in the screen. However the test results as failed.
index.html:
<div ui-view="!admin">
<h1> Please sign up </h1>
</div>
<div ui-view="admin">
<h1> Welcome home soldier </h1>
</div>
index_spec.js:
If I do this then the test fails:
expect($('[ui-view="admin"]').isDisplayed()).toBe(true);
If I do this then the test success:
expect($('[ui-view="admin"]').isDisplayed()).toBe(false);
I have tried to do isPresent(), but it gives me the same result.
If try this, do you get the good result ?
browser.wait(function () {
return $('[ui-view="admin"]').isDisplayed();
}, 5000);
expect($('[ui-view="admin"]').isDisplayed()).toBe(true);
Please check if your HTML or CSS doesn't have the elements as hidden - using display:none or display:block, under which the isDisplayed() method would return false. This is as defined by the code for isDisplayed() method here.
Also, you can checkelement.size()!=0 to check if it's displayed (it's not a full proof solution though)

"Unable to resolve constructor for: '"dojox.mobile.TextBox"'"

I am facing following issue while working with dojo inline template:
I am creating the template in a html page by defining the template in between the following tags(It has mvc also integrated)
`<script id="createNewItem" type="text/template">
<div>
<div data-dojo-type='dijit/TitlePane' data-dojo-props='open:false'>
<div class='accordionRev'>
<input type="number" name="qty" placeholder="Quantity (required)" data-dojo-type="dojox.mobile.TextBox" class='quantity' data-dojo-props="value: at('rel:','quantity'), class:at('rel:', 'quantityErr')" onchange="cntrl.createQuoteFields(true, this, '{{lineNumber}}');" onkeypress="cntrl.quantityHandler.call(this, '{{lineNumber}}')" onpaste="cntrl.pastehandler.call(this)" tabindex=0/>
</div>
</div>
</div>
</script>'
I will be using this template in another page like this
`<ul id="rfqTitlePane" class="hide"
data-dojo-type="dojox/mvc/WidgetList"
data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
data-dojo-props="children: at(cntrl.createQuoteList,'items').direction(at.from)"
data-mvc-child-type="dojox/mvc/Templated"
data-mvc-child-props="clickable: true, variableHeight: 'true',
indexAtStartup: this.indexAtStartup,
customTitle: at(this.target, 'title').direction(at.both), titlePaneDOM:at(this.target,'displayDetails').direction(at.from).transform({format:custom.helpers.RequestMarkup})">
<script type="dojox/mvc/InlineTemplate">
<li>
${titlePaneDOM}
</li>
</script>
</ul>`
I am getting "Unable to resolve constructor for: '"dojox.mobile.TextBox"'" error. I actually defined textbox before the template gets loaded. I am not sure where its going wrong
It appears that the question contains wrong markdown, so I'd recommend fixing that so that better answers can be provided. Meanwhile some things I can say are:
You may want to try importing dojox/mobile/TextBox module before running the template.
Recent releases of Dojo prefers AMD format in data-dojo-type e.g. data-dojo-typ="dojox/mobile/TextBox".
dojox/mvc/InlineTemplateMixin looks at <script type="dojox/mvc/InlineTemplate"> instead of <script type="text/template">.
Hope this helps.
Best, Akira

PhantomJS rewriting URL in backgroundImage property to local file system

I am using PhantomJS to do some rewriting of HTML. I'm adding a background-image property to an element. But when I write out the resulting DOM, the URL has been rewritten to a local URL. I've boiled this down to the following test case:
JS
var page = require('webpage').create();
page.open("test.html",function(){
setTimeout(function(){
page.evaluate(function(){
document.getElementById("test").style.backgroundImage="url(test.png)";
});
console.log(page.content);
phantom.exit();
},1000);
});
HTML
<html>
<body>
<div id="test"></div>
</body>
</html>
Output
$ phantomjs test.js
<html><head></head><body>
<div id="test" style="background-image: url(file:///C:/cygwin/tmp/test.png); ">
</div>
</body></html>
UPDATE
The problem remains if you specify ./test.png or //test.png. However, http://example.com/test.png is left unchanged, as might be expected.
If this HTML document is opened in Chrome, and the background-image property added to the div element in the style inspector, the URL is unmodified, whether the document is inspected in the Elements tab in devtools, or via document.body.innerHTML displayed in the console, or copying the HTML.
UPDATE 2
I just found out that if the document is located in Chrome, and the command elt.style.backgroundImage="url(test.png"); is issued in the console, then the URL is rewritten. So at the end of the day it appears that this is not a PhantomJS issue, although I still don't understand this behavior.
Obviously, I don't want this URL to be rewritten in this fashion, and I don't understand why PhantomJS feels the need to do this. Ideas?