Codeception 2.1 PageObject doesn't work - codeception

Looks like PageObject doesn't work any more in Codeception 2.1
exactly it is impossible to use methods in PageObject class!
I do not want to put any methods to AcceptancTtester class, I would like to keep it as on example in codeception website in PageObject class
Just simply try to reproduce provided by codeception example from this page http://codeception.com/docs/06-ReusingTestCode#PageObjects
When try to run will get an error like:
[PHPUnit_Framework_Exception] Argument 1 passed to Page\Login::__construct() must be an instance of Page\AcceptanceTester
I guess it is because of _bootstrap.php is empty now
Could some one tell what we should I add to _bootstrap.php file (Before it profiled automatically while creating new Page using generate command from console)

It looks like a bug in documentation:
AcceptanceTester is not in the Page namespace.
Change
public function __construct(AcceptanceTester $I)
to
public function __construct(\AcceptanceTester $I)

Related

Pass value to xpath at runtime

Please read the whole Q before disliking or commenting something. I have searched on internet before posting it here. I'm having the below project structure.
pages(package)
> Homepage.java
test(package)
> Flipkart.java
Inside Homepage.java i have declared all the WebElements using POM Page Factory methods and created respective method to click on Electronics link.
#FindBy(xpath = '//input[#title='Electronics']')
private WebElement lnkElectronics;
Inside Fipkart.java I'm calling the Electronics click method.
My doubt over here is the declared WebElement is specifically for Electronics.
Is there a way i can create a WebElement with type like mentioned below and pass value for %s dynamically from main method?
#FindBy(xpath = '//input[#title='%s']')
private WebElement lnkElectronics;
Answer referenced from Page Object Model in Selenium
You cannot create a FindBy with Variable, FindBy accepts only constants.
In case if you want to achieve that variability then you should write or find the element using normal findElement method
As per the Test Design Consideration following Page Object Design Pattern :
A Page Object is an object-oriented class that serves as an interface to a page of the Application Under Test. Your #Tests uses the methods of this Page Object class whenever they need to interact with the User Interface of that page. The benefit is that if the UI changes for the page your #Tests themselves don’t needs to be changed. Only the code within the Page Object needs to be changed.
Advantages :
Clean separation between test code and page specific code such as locators, methods and layout.
A single repository for the operations offered by the page rather than having these services scattered throughout the tests.
Based on these Page Factory features you won't be able to create any generic WebElement for which you can pass value dynamically from main() or #Test annotated method e.g.
#FindBy(xpath = '//input[#title='%s']')
private WebElement lnkElectronics;
You can find almost a similar discussion in Where should I define modal specific code in Selenium Page Object Model pattern
WorkAround : on page class you can define a method, and can pass the text on the fly from the calling class to click on specific tab
if you want to click any common text on the page. You can create a method as given below and can pass the text on the fly to click on that specific tab on that page
public void clickTab(String tabText){
String tabxpath = "//div[contains(text(), '" + tabText + "')]";
driver.findElement(By.xpath(tabxpath)).click();
}

How can I access the WebDriver module from within an AcceptanceTester?

I have a test, where I an trying to change the configuration:
$this->getModule('WebDriver')->_reconfigure([...]);
This shows what I am trying to do under "Dynamic Configration": http://codeception.com/docs/06-ReusingTestCode#.VnXNjq6rTUI
Edit:
It appears that I have to call this on the moduleContainer, but this is located at:
$I->scenario->test->moduleContainer->getModule('WebDriver')->_getConfig('url');
However $test is under private access, and there is no getTest() method.
Documentation says: You may call it from a helper class and pass in all the fields you want to change.
Add reconfigure method to your Acceptance helper and call it from your test.

Create a Reusable method to Verify list elements by Selenium WebDriver

I am new to this site and don't know how things show up here. I was reading the post from below where String array is being used to ListwebElements.
Verify list elements by Selenium WebDriver
String[] expected = {"GRAM", "OUNCE", "POUND", "MILLIMETER", "TSP", "TBSP", "FLUID_OUNCE"};
I am trying to do something similar using String Array trying to get different buttons on a UI page. I want to make this method reusable by changing the "expected" list per test. Does anyone know how you would make this method Reusable?
In my case, "expected" list is different each time depending on a page.
I would suggest to use the custom annotation for reusing purpose. Please see the example here.
If you are using JUnit you can also use parameterized test

Rangy injection module issue

I'm trying to inject the rangy javascript core and serializer code base (https://code.google.com/p/rangy/) into an html page. However when I inject it, the rangy object isn't created properly. The modules are added at rangy.modules.* however the functions created within the module are not added to the rangy object. Also the modules all have the following variables 'initialized' and 'supported' as false. Has anyone been able to inject the Rangy code base into their web page properly or can provide any assistance?
To inject - open up Chrome javascript console and insert code as minified (very important or it will not work - http://jscompress.com/):
javascript: insert code here
You can call rangy.init() to initialize Rangy after the page has loaded.

Behat / Mink / Selenium: intercepting AJAX calls possible?

I am using Behat/Mink with Selenium for acceptance testing. I need to determine if my web page is making a badly formed call to the server via Ajax. The problem is, the server will attempt to "correct" badly-formed code and return valid data nonetheless.
Is there a way to "intercept" and validate ajax calls made from my website?
Right now my FeatureContext class looks like:
public function performAnAction()
{
$this->enterInField('test', 'field');
$this->hitOKButton();
$this->assertResponseContains('success');
}
I would like to do something like:
public function performAnAction()
{
$this->enterInField('test', 'field');
$this->hitOKButton();
$ajax = $this->getAllAjaxCalls();
foreach ($ajax as $call) {
// perform some validation
}
$this->assertResponseContains('success');
}
Here are two great resources for doing checks on ajax calls
The behat mink way
http://docs.behat.org/cookbook/behat_and_mink.html#defining-our-own-featurecontext
This is a neat solution using _before and _after overrides to getting deeper inside the base functionality and is very interesting but reading through it will help you get a better understanding of what the framework is really doing under the covers
http://blog.scur.pl/2012/06/ajax-callback-support-behat-mink/
I think you could simply use the built in wait function with the js callback to get what you want in your custom step def by putting your response into a jquery data[] object on any html element and verify your expected output that way.
$this->getSession()->wait(5000,
"$('.someCssClassSelectorToElementWithResponseStuff').length > 0"
);
If your element were a js object that would work
Or if it comes back as a jquery object you could use .size() instead of length
just make sure your injected js evaluates to true of false to get your pass/fail