play 2.5 render view test, access to flash messages - testing

Here the simple play render view test. In view template i trying to accesss session information throught flash.get().
But test failed with message There is no HTTP Context available from here. How add fake session data to tested application in junit test context?
public class ApplicationTest extends WithServer {
private FormFactory formFactory() {
return app.injector().instanceOf(FormFactory.class);
}
#Test
public void renderTemplate() {
Content html;
session().put("session","123");
html = index.render(formFactory().form(Auth.Login.class));
assertTrue(contentAsString(html).contains("Hello"));
}
}
Test ApplicationTest.renderTemplate failed: java.lang.RuntimeException: There is no HTTP Context available from here., took 0.544 sec
at play.mvc.Http$Context.current(Http.java:57)
at play.mvc.Http$Context$Implicit.flash(Http.java:307)
at views.html.index_Scope0$index$$anonfun$apply$1.apply(index.template.scala:39)
at views.html.index_Scope0$index$$anonfun$apply$1.apply(index.template.scala:38)
at views.html.helper.form_Scope0$form.apply(form.template.scala:35)
at views.html.index_Scope0$index.apply(index.template.scala:38)
at views.html.index_Scope0$index.render(index.template.scala:141)
at views.html.index.render(index.template.scala)
at ApplicationTest.renderTemplate(ApplicationTest.java:37)

Using WithServer starts up an application that you can make requests to. For the tests you describe here, you need to use WithApplication.
To manually set a context, you can override the startPlay method.
#Override
public void startPlay()
{
super.startPlay();
Http.Context.current.set(new Http.Context(1L,
Mockito.mock(RequestHeader.class),
Mockito.mock(Http.Request.class),
Collections.<String, String>emptyMap(),
Collections.<String, String>emptyMap(),
Collections.<String, Object>emptyMap()));
}

Related

How to write a PHPUnit test for a SOAP server?

UPD. Sorry, guys.
I have an application that acts as a SOAP server, how do I write a PHPUnit test to test it?
SOAP extension is reading data from PHP input stream. You just provide your own data there and create some integration/unit tests for your API.
Take a look at the signature of SoapServer::handle() method. It takes as an argument a string which is a request itself. This parameter is optional and if you don't pass anything in, PHP will just read the data itself. But you can simply override it.
I used streams to do it. First you wrap the SoapServer with your own class like this:
class MyServer
{
/** \SoapServer */
private $soapServer;
public function __construct(\SoapServer $soapServer)
{
$this->soapServer = $soapServer;
}
public function handle(Psr\Http\Message\StreamInterface $inputStream): void
{
$this->soapServer->handle($inputStream->getContent());
}
}
Now you are ready to mock the request.
In your test you can do:
class MyTest extends TestCase
{
public function testMyRequest(): void
{
$mySoapServer = $this->createMySoapServer();
$request = $this->createRequest();
$mySoapServer->handle($request);
}
private function createRequest(): StreamInterface
{
$requestString = '<soap:Envelope></soap:Envelope>';
$fh = fopen('php://temp', 'rw');
fwrite($fh, $requestString);
fseek($fh, SEEK_SET);
return new Psr\Http\Message\StreamInterface\Stream($fh);
}
private function createMySoapServer(): MyServer
{
return new MyServer(new \SoapServer());
}
}
One thing to keep in mind - this test will generate output. You may want to test this output or ignore it. Depends on your use case.
Another side note. What you are asking for has really nothing to do with PHPUnit. It just a matter of designing your SOAP server correctly.
If you are wondering how to set up the stream when you have a live request, this is really simple:
$server->handle(new Psr\Http\Message\StreamInterface\Stream(fopen('php://input', 'r+')));

Wicket Deployment mode map resources wrong way

I have Page
getRootRequestMapperAsCompound().add(new NoVersionMapper("/card/${cardId}", CardPage.class));.
On this page there is TinyMCE4 editor. Which try to load images using relative path "images/1.jpg"
I've added resource mapping to allow images successfuly loaded.
mountResource("/card/image/${imageId}", imageResourceReference);
In DEVELOPMENT mode everything work nice, image are loaded in to editor, but in DEPLOYMENT mode, Page has been called twice, first time for /card/1 and second time for /card/image/1.jpg.
How to correctly mount resources for DEPLOYMENT mode?
UPDATE look like found the reason
public int getCompatibilityScore(Request request)
{
return 0; // pages always have priority over resources
}
, but then the question is: "Why it is working nice in development mode"?
Update 2 I haven't find better solution then add my own Resource Mapper with overrided getCompatibilityScore()
public class ImageResourceMapper extends ResourceMapper {
private String[] mountSegments;
public ImageResourceMapper(String path, ResourceReference resourceReference) {
super(path, resourceReference);
mountSegments = getMountSegments(path);
}
public ImageResourceMapper(String path, ResourceReference resourceReference, IPageParametersEncoder encoder) {
super(path, resourceReference, encoder);
mountSegments = getMountSegments(path);
}
#Override
public int getCompatibilityScore(Request request) {
if (urlStartsWith(request.getUrl(), mountSegments)) {
return 10;
}
return 0;
}
}

Managing web driver code separately

Can you help me with this question.
I am working on a test automation framework and I want to keep my webdriver code separately and initiate from my test cases.
please help me in this. - Thanks
Go for the POM Model with Encapsulation . In the Example below I have created a Test Setup class which can then be used in all the test classes.
So this would be you TestSetup Class-
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
namespace dummy
{
[SetUpFixture]
public class TestSetup
{
public static IWebDriver driver;
[OneTimeSetUp]
public void testSetup()
{
if (driver == null)
{
//Local Tests
driver = new FirefoxDriver();
}
}
public static bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
[OneTimeTearDown]
public void TearDown()
{
driver.Quit();
}
}
}
And Below can be you TestCase Class . Notice that you are just calling the test setup .So your test class will inherit all the functions from the Primary class-TestSetup
using System;
using OpenQA.Selenium;
using NUnit.Framework;
using System.Threading;
namespace dummy
{
[TestFixture]
[Parallelizable]
public class TESTCASE
{
IWebDriver driver = TestSetup.driver;
[Test]
public void siteVisit()
{
driver.Navigate().GoToUrl("http://google.com");
Assert.IsTrue(String.Equals("Google, driver.Title));
}
}
}
Hi if i have understood it correctly then please go for POM (Page object Framework)
1.The main advantage of Page Object Model is that if the UI changes for any page, it don’t
require us to change any tests, we just need to change only the code within the page objects
(Only at one place).
2.Page Object model is writing all the functionalities / reusable components of a page that
we want to automate in a separate class.
3.As per google wiki Page object **"Within your web app’s UI there are areas that your tests
interact with. A Page Object simply models these as objects within the test code. This
reduces the amount of duplicated code and means that if the UI changes, the fix need only
be applied in one place."**
Example : google home page
1.Say now if we consider our google home page as Home page.
2.For the above pages we will create class as HomePage.class.
3.In class we will identify and write reusable methods which are specific to Home page.
4.'google home page' which will have many options like Search, Sign In, +You, Images etc.
5.Now all functionalities that we want to automate should have reusable methods/components
for each page.
6.as our main page is google page we can navigate to other pages by clicking on any link
from the google page. When ever we are navigating to other page, we need to return that page
object. Else Return the current page object as this action doesn't navigate to a other page
represented by another Page Object.
advantages.
1.There is clean separation between test code and page specific code such as locators
(or their use if you’re using a UI map) and layout.
2.There is single repository for the services or operations offered by the page rather than
having these services scattered through out the tests.
In both cases this allows any modifications required due to UI changes to all be made in one place.Click for more on POM

Using SpecFlow, Selenium and FluentAutomation causing problems

I am currently using Specflow with Selenium and FluentAutomation, and am running into significant problems with maintaining state between steps in specflow.
See my example code below:
[Binding]
public class RegistrationSteps : FluentTest
{
[Given(#"I create an account")]
public void GivenICreateAnAccount()
{
new HomePage(this)
.Go()
.StartRegistration()
.EnterDetailsAndClickSubmit(); // takes me to deposit page
}
[When(#"Deposit '(.*)' dollars in my account")]
public void GivenDepositMoneyInMyAccount(int amount)
{
new DepositPage(this)
.EnterDetailsAndClickSubmit(amount);
}
}
My problem is:
In the first step the page is loaded using Go() and everything happens fine
In the second step my tests continue, here I expect I am on a different page, based in the Submit in the previous
Because I am no on a different PageObject it gets confused, I don't use Go because the previous step shouldve brought me here, and at this stage it wont find the expected elements
So my question is, how can I use one browser session and several PageObjects across multiple Specflow tests?
According to the FluentAutomation doc, you should do something like this:
[Binding]
public class RegistrationSteps : FluentTest
{
private PageObject _currentPage;
[Given(#"I create an account")]
public void GivenICreateAnAccount()
{
_currentPage = new HomePage(this)
.Go()
.StartRegistration()
.EnterDetailsAndClickSubmit(); // takes me to deposit page
}
[When(#"Deposit '(.*)' dollars in my account")]
public void GivenDepositMoneyInMyAccount(int amount)
{
_currentPage = _currentPage
.EnterDetailsAndClickSubmit(amount);
}
}
Provided that you return the page object that is switched to in the EnterDetailsAndClickSubmit method of your concrete page object like:
Public PageObject EnterDetailsAndClickSubmit() {
// [.. enter details here and click submit ..]
return this.Switch();
}

How to find port of Spring Boot container when running a spock test using property server.port=0

Given this entry in application.properties:
server.port=0
which causes Spring Boot to chose a random available port, and testing a spring boot web application using spock, how can the spock code know which port to hit?
Normal injection like this:
#Value("${local.server.port}")
int port;
doesn't work with spock.
You can find the port using this code:
int port = context.embeddedServletContainer.port
Which for those interested in the java equivalent is:
int port = ((TomcatEmbeddedServletContainer)((AnnotationConfigEmbeddedWebApplicationContext)context).getEmbeddedServletContainer()).getPort();
Here's an abstract class that you can extends which wraps up this initialization of the spring boot application and determines the port:
abstract class SpringBootSpecification extends Specification {
#Shared
#AutoCleanup
ConfigurableApplicationContext context
int port = context.embeddedServletContainer.port
void launch(Class clazz) {
Future future = Executors.newSingleThreadExecutor().submit(
new Callable() {
#Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication.run(clazz)
}
})
context = future.get(20, TimeUnit.SECONDS);
}
}
Which you can use like this:
class MySpecification extends SpringBootSpecification {
void setupSpec() {
launch(MyLauncher.class)
}
String getBody(someParam) {
ResponseEntity entity = new RestTemplate().getForEntity("http://localhost:${port}/somePath/${someParam}", String.class)
return entity.body;
}
}
The injection will work with Spock, as long as you've configured your spec class correctly and have spock-spring on the classpath. There's a limitation in Spock Spring which means it won't bootstrap your Boot application if you use #SpringApplicationConfiguration. You need to use #ContextConfiguration and configure it manually instead. See this answer for the details.
The second part of the problem is that you can't use a GString for the #Value. You could escape the $, but it's easier to use single quotes:
#Value('${local.server.port}')
private int port;
Putting this together, you get a spec that looks something like this:
#ContextConfiguration(loader = SpringApplicationContextLoader, classes = SampleSpockTestingApplication.class)
#WebAppConfiguration
#IntegrationTest("server.port=0")
class SampleSpockTestingApplicationSpec extends Specification {
#Value("\${local.server.port}")
private int port;
def "The index page has the expected body"() {
when: "the index page is accessed"
def response = new TestRestTemplate().getForEntity(
"http://localhost:$port", String.class);
then: "the response is OK and the body is welcome"
response.statusCode == HttpStatus.OK
response.body == 'welcome'
}
}
Also note the use of #IntegrationTest("server.port=0") to request a random port be used. It's a nice alternative to configuring it in application.properties.
You could do this too:
#Autowired
private org.springframework.core.env.Environment springEnv;
...
springEnv.getProperty("server.port");