How can I use my classes in Behat + Mink? - behat

I have large (1000+ lines) FeatureContext class and I want to split this file in several logical parts. But I don't know how to create my own classes in Behat. I read docs http://docs.behat.org/en/v2.5/guides/4.context.html but I don't get it. And in docs example FeatureContext extends BehatContext, but I need FeatureContext extends MinkContext, because Mink doesn't work without it. If you can write example of my own class with function that use Mink and show me how to use this class in FeatureContext that would be great

This configuration should achieve what you need
file: behat.yml
default:
suites:
yourCustomSuite:
paths:
- %paths.base%/src/your/bundle/name/Features/YourSuiteName
contexts:
- YourBundleName\Contexts\YourContextName
file: YourBundleName\Contexts\YourContextName.php
class YourContextName extends FeatureContext
{
}
and let FeatureContext extend \Behat\MinkExtension\Context\MinkContext

I just found right way to use subcontexts (classes) in Behat with Mink http://blog.scur.pl/2012/06/subcontexts-behat-mink/
Hope it will help somebody

Look for PageObjectExtension.
Page object pattern is a way of keeping your context files clean by separating UI knowledge from the actions and assertions.
I've used the PageObjectsExtension in my project and my Contexts look's like this:
/**
* #When /^I order products by "([^"]*)"$/
*
* #param $order
*/
public function orderProductsBy($order)
{
$this->getPage("Catalog")->orderProductsBy($order);
}
Configure extension on behat.yml
SensioLabs\Behat\PageObjectExtension:
namespaces:
page: [NS1\Features\Page, NS2\Features\Page]
element: [NS1\Features\Page\Element, NS2\Features\Page\Element]
If you need multiple Contexts, you can add it in your behat.yml
default:
suites:
selenium:
mink_session: selenium
mink_javascript_session: selenium
contexts:
- Namespace\FeatureContext
- Namespace\CatalogContext
- Namespace\CheckoutFinishContext
- Namespace\CheckoutIndexContext
- Namespace\HomeContext
- Namespace\ProductDetailsContext
- Namespace\CartContext
- Namespace\CustomerAccountContext
- Namespace\CustomerLoginContext
- Namespace\FilterContext
- Namespace\TelesalesContext
- Namespace\HelpdeskContext
- Namespace\FaqContext
- Namespace\BrandContext

Related

Intellij not adding default javadoc comments with (/** + Enter)

I have a file and Code Template setup for Class files under my intellij settings
as
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME} {
}
I have some standard format setup in Header.java which I want to use everywhere.
So whenever I create a new java class I get the content of Header.java on top of class as comment.
But, If somehow I have an existing java class without the comment and I type /** + Enter I only get this
/**
*
*/```
I'm unable to find where to set these code template to have default class level javadoc comment to be created upon `/** + Enter`
Using community Addition.

Is it possible write documentation for TestCafe tests using JSDocs?

We would like to generate a living documentation for our team's TestCafe testing framework.
Instead of having separate wiki / separate document to maintain info about the framework, we're exploring option like JSDocs.
The JSDoc templates looks something like below:
/**
* Represents a book.
* #constructor
* #param {string} title - The title of the book.
* #param {string} author - The author of the book.
*/
So how to make them more meaningful for documenting our TestCafe tests?
Thanks
Test cases are function calls. JsDoc is not built to document function calls. It is primarily built to document classes, methods, and property declarations, not invocations.
One of the approaches would be to extract your test case code to a separate function and document it. For instance:
import { Selector } from 'testcafe';
fixture `My fixture`
.page `http://devexpress.github.io/testcafe/example/`;
test('Test a book', async t => {
test_a_book(t, 'title', 'author');
});
/**
* Represents a book.
* #param {string} title - The title of the book.
* #param {string} author - The author of the book.
*/
async function test_a_book(t, title, author) {
await t
.typeText('#title', title)
.typeText('#author', author)
.click('#submit-button')
.takeScreenshot({
path: 'books/book.png',
fullPage: true
});
}
You can also extract your test case logic to a Page Model where you can document everything.
Also, you can define the function invocation as a #property or create a custom #tag, but JsDoc does not produce nice-looking documentation for these workarounds.

How we can run more than one feature files and all feature files depending on the requirement using same runner class?

I have 5 feature files I want to run some feature files depends on the requirement using one runner class only is it possible and if then how?
1) You can run required feature adding path to the feature in Karate Options:
#RunWith(Karate.class)
#KarateOptions(features = "classpath:animals/cats/required.feature")
public class CatsPostRunner {
}
2) You can run required feature or scenario adding a tag to the feature or scenario and in Karate Options:
#RunWith(Karate.class)
#KarateOptions(tags = "#someTag")
public class CatsPostRunner {
}
3) Also you can combine approach 1 and 2 :
#RunWith(Karate.class)
#KarateOptions(features = "classpath:animals/cats/required.feature", tags = "#someTag")
public class CatsPostRunner {
}
More info you find in Karate Options.

What is the difference in setBrowserUrl() and url() in Selenium 2 web driver for phpunit?

In many examples, I have seen calls made to both webdriver->setBrowserURL(url) and webdriver->url(url). Why would I want to use one instead of the other. One such example shows using both in the same manner (taken from the phpunit manual):
<?php
class WebTest extends PHPUnit_Extensions_Selenium2TestCase
{
protected function setUp()
{
$this->setBrowser('firefox');
$this->setBrowserUrl('http://www.example.com/');
}
public function testTitle()
{
$this->url('http://www.example.com/');
$this->assertEquals('Example WWW Page', $this->title());
}
}
?>
Why would setBrowserUrl() be called once in setup -- and then url() be called with the identical url in the test case itself?
In other examples, I've seen url() called with just a path for the url. What is the proper usage here? I can find almost no documentation on the use of url().
setBrowserUrl() sets a base url, allowing you to use relative paths in your tests.
The example from the phpunit manual is kind of confusing - I believe setBrowserUrl() is being used during setup simply because it'll throw an error without it:
public function start()
{
if ($this->browserUrl == NULL) {
throw new PHPUnit_Framework_Exception(
'setBrowserUrl() needs to be called before start().'
);
}
$this->url will use this base if a relative path is given.

Geb page url method from ConfigSlurper

I am trying to store the urls I need in a config file that gets pulled using ConfigSlurper. I think this may not work but not sure. Thoughts?
You are probably looking for functionality provided by baseUrl configuration. When using to MyPage the url which is used by the browser is determined by combining basUrl configuration and the url property of your page class.
If you wanted a slightly cleaner method of doing this, you could implement a base page such as the one below - inner class for brevity and to avoid calling protected methods directly - (we have apps on 26 different subdomains!):
package page.admin
import geb.Configuration
import geb.Page
class AdminPage extends Page {
class WrappedConfig extends Configuration {
WrappedConfig(ConfigObject rawConfig) {
super(rawConfig)
}
String getAdminBaseUrl() {
return readValue('adminUrl', '<invalid-url>')
}
}
String getPageUrl() {
WrappedConfig config = new WrappedConfig(browser.config.rawConfig)
return config.adminBaseUrl + this.class.url
}
}
Your config might look something like this:
baseUrl = 'http://base-app.example.net'
adminUrl = 'http://admin-app.example.com'
This way, you can still use normal geb syntax:
given:
to PageWhichExtendsAdminPage, 'your-path', key1: 'value1
to generate the url http://admin-app.example.com/your-path/?key1=value1
I run geb on different locales so I encountered the same issue. I usually load the different urls out of a config file with locale.getCountry() as parameter for the environment.
In the running class I replace the baseUrl with the loaded entry with the ConfigSlurper. The advantage is that I can handle multiple locales and localhost environments. Testing locally vs testing the staging environment.
I have one main spock file containing the whole regression testing and a inheriting spock class for every country. The inheriting spock files doesn't contain much except the country/language encoding in the class name.
The config file:
environment{
CA{
url="ca.somewhere.com"
validZipCode=...
...
}
...
}
The main class:
class MainRegression extends GebReportingSpec{
#Shared Locale locale
def setupSpec(){
...
locale = ParameterReader.getLocale(this.class.name)
...
}
def "testing the website"(){
when: "entering the main url"
go URLService.getBaseUrl(locale)
...
}
The inheriting class:
#Stepwise
class CaEnRegressionSpec{} // Canada with english language
A good way to handle the at-verification with different languages / locales:
http://ldaley.com/post/1013531080/painless-page-identification-with-geb-grails