assets are not loaded in functional test mode
Asked Answered
Q

4

7

The answer to my problem is probably very simple and stupid but, can't find it by myself so far. Using Play Framework, emberjs and FluentLenium, I wrote a very simple functional test but can't make it works under IntelliJ IDEA 13. For some reason, every assets located in the public/ and app/ folders are not found when I run the test with IntelliJ.

Here's my code :

import org.junit.Test;
import play.libs.F.Callback;
import play.test.TestBrowser;
import play.test.WithApplication;

import static org.fest.assertions.Assertions.assertThat;
import static play.test.Helpers.*;

public class HomePageTest extends FluentTests {

    @Test
    public void hello_world_test() {
        running(testServer(3333, fakeApplication(inMemoryDatabase())), FIREFOX, new Callback<TestBrowser>() {
            public void invoke(TestBrowser browser) {
                HomePage homePage = new HomePage(browser.getDriver());
                homePage.go();
                homePage.isAt();
                assertThat(browser.pageSource()).contains("Hello world!");
            }
        });
    }
}

public class HomePage extends BaseFluentPage {

    public HomePage(WebDriver driver) {
        super(driver);
    }

    @Override
    public String getUrl() {
        return BASE_URL;
    }

    @Override
    public void isAt() {
        await().atMost(TIMEOUT).until(".ember-application").isPresent();
    }
}

public abstract class BaseFluentPage extends FluentPage {

    protected static final String BASE_URL = "http://localhost:3333/#/";
    protected static final int TIMEOUT = 5000;

    protected BaseFluentPage(WebDriver driver) {
        super(driver);
    }
}

Here's the error message I receive in IntelliJ IDEA logs :

[[36mdebug[0m] application - Unforseen error for lib/jquery/jquery.js at /public
java.lang.RuntimeException: no resource
    at controllers.Assets$$anonfun$controllers$Assets$$assetInfoFromResource$1$$anonfun$10.apply(Assets.scala:214) ~[play_2.11-2.3.0.jar:na]
    at controllers.Assets$$anonfun$controllers$Assets$$assetInfoFromResource$1$$anonfun$10.apply(Assets.scala:214) ~[play_2.11-2.3.0.jar:na]
    at scala.Option.getOrElse(Option.scala:120) [scala-library-2.11.1.jar:na]
    at controllers.Assets$$anonfun$controllers$Assets$$assetInfoFromResource$1.apply(Assets.scala:214) ~[play_2.11-2.3.0.jar:na]
    at controllers.Assets$$anonfun$controllers$Assets$$assetInfoFromResource$1.apply(Assets.scala:213) ~[play_2.11-2.3.0.jar:na]

Thanks!

UPDATE:

My config is almost brand new. I used the activator command line to create the project and generate the idea config files. Here's a look to my current folder structure (I list only the ones missing when I run my integration tests) :

app >>
    assets >>
        javascripts >>
            app.js
public >>
    stylesheets >>
        style.css
    images >>
        favicon.ico

Everything is working when I run my test with the command line

activator test

UPDATE 2

Since I didn't find the solution yet, I provide more code and infos on my configuration so maybe someone will spot the problem.

index.scala.html :

<html>
    <head>
        <title>Facebook-API</title>

        <link rel="stylesheet" media="screen" href="@routes.Assets.at("lib/bootstrap/css/bootstrap.min.css")">
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/style.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">

        <script src="@routes.Assets.at("lib/jquery/jquery.js")"  type="text/javascript"></script>
        <script src="@routes.Assets.at("lib/bootstrap/js/bootstrap.min.js")"></script>
        <script src="@routes.Assets.at("lib/handlebars/handlebars.js")"  type="text/javascript")"></script>
        <script src="@routes.Assets.at("lib/emberjs/ember.js")"  type="text/javascript"></script>
        <script src="@routes.Assets.at("lib/emberjs-data/ember-data.js")"  type="text/javascript")"></script>
        <script src="@routes.Assets.at("javascripts/app.js")"  type="text/javascript")"></script>
    </head>
    <body>
        @ember_content
    </body>
</html>

plugins.sbt :

resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.2")

// web plugins

addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.1")

addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-web" % "1.0.2")

build.sbt :

name := """facebook-api"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayJava, SbtWeb)

scalaVersion := "2.11.1"

libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  cache,
  javaWs,
  "org.webjars" % "bootstrap" % "3.2.0",
  "org.webjars" % "jquery" % "2.1.1",
  "org.webjars" % "handlebars" % "1.3.0",
  "org.webjars" % "emberjs" % "1.5.0",
  "org.webjars" % "emberjs-data" % "1.0.0-beta.8"
)

UPDATE 3:

I updated again my post to reflect my current project structure and code (see above). I modified my code to use WebJars instead of manually downloaded js libs, followed the steps of migration to Play 2.3.X, updated to the last Play version and followed the steps to correctly import a SBT & Play project in IntelliJ specified in Play documentation. Now, when I run my tests from IntelliJ, I still get the same error but, I can see that there's a web/ folder generated in target/ containing a folder test/ which contains every assets I have in my project with the correct folder structure. I added this folder as a Resource/Test Resource folder in IntelliJ but still no success. I also added my public folder with the same result.

I really feel I'm getting closer to the solution. In fact, I tried many things and found that if I remove the sbt-rjs plugin (which is RequireJS), running code in dev (activator run) crashed with the same error. I didn't set yet RequireJS (add the main.js file) for my JS files and don't want to do it until I really need it except if it solves my problem. Any thoughts about it?

Quincyquindecagon answered 16/7, 2014 at 22:36 Comment(5)
Make sure your "public" directory is marked as a resource (or source) directory. (Right click it in the project view and select "Mark Directory as...". You can also configure this in the Project Structure (File > Project Structure) dialog. If that does not help, please update your question with more details on your project configuration.Holsinger
Thanks Mark for your comment. Unfortunately, this didn't solve the problem even if I feel we're really close to it. Just to add infos on top of that, even the JS files in the app folder aren't loaded (same for css files)... I'll update my question right away to add infos on my configQuincyquindecagon
I'm not sure about your specific error, but some general thoughts on this: (1) I also experienced IntelliJ test failures in the past; it may have had something to do with the use of FIREFOX. Try the headless browser. (2) I've come to use the ~test workflow, where I enter that in activator and just bypass IntelliJ completely. (3) We're also using Play + Ember and have completely separated these projects. I actually can't find a benefit to combining them, especially because for launch, Ember is just all static files anyway. HTH.Krp
Hi @JoshPadnick, thanks for your help. (1) I tested with the headless browser without success. The problem stay the same, all my assets files (js, css) are not loaded and print out a not found exception. (2) Indeed I'm thinking more and more about this option especially because what I like more about IDEA is running tests with coverage. If I can use it, it comes to me useless. (3) The final goal of my project is to separate them but for now, we just want something that works so we can develop and test and we go. Anyway, I still need my css files to be loaded, and they don't.Quincyquindecagon
I'm having the same problem and created an issue here - github.com/playframework/playframework/issues/3234Boigie
Q
8

Finally, here's the solution to this problem.

I added this line to my build.sbt file :

For SBT 0.x:

unmanagedResourceDirectories in Test <+=  baseDirectory ( _ /"target/web/public/test" )

For SBT 1.x:

unmanagedResourceDirectories in Test +=  baseDirectory ( _ /"target/web/public/test" ).value

Thanks to @MarkVedder and @JarmoPertman for their great comments who put me on this solution!

Quincyquindecagon answered 31/7, 2014 at 6:5 Comment(0)
A
3

For others that come looking for a solution to this, we were having problems getting assets to load properly in our functional test run under Scala 2.12 and Play Framework 2.6. Following the advice on the accepted answer here, we tried adding:

unmanagedResourceDirectories in FunctionalTest += 
  baseDirectory ( _ /"target/web/public/test" ).value

And that appeared to work - at least locally. However, things were still failing on our CI side. Mentioned in another comment here was this old Play Framework issue: https://github.com/playframework/playframework/issues/3234, we tried adding the web-test:assets command prior to running our functional test suite, and that also appeared to fix it as we could see locally that the assets got moved into the target/web/public/test directory. Still having problems though getting it to consistently pass or pass at all on our CI side.

Knowing that sbt-web was involved in this process, going back over the sbt-web docs there was a little hidden item in the readme on https://github.com/sbt/sbt-web:

To automatically add the production-ready assets to classpath, the following might be useful:

(managedClasspath in Runtime) += (packageBin in Assets).value

Modifying that line slighty to work with our FunctionalTest config:

(managedClasspath in FunctionalTest) += (packageBin in Assets).value

and now it is passing ALL THE TIME both locally and on CI. No other SBT lines were needed, and we REMOVED the

unmanagedResourceDirectories in FunctionalTest +=
  baseDirectory ( _ /"target/web/public/test" ).value

line as it was no longer needed.

Appointive answered 25/1, 2019 at 14:12 Comment(0)
P
1

I recently had a similar problem. I solved it double checking this steps according to Play 2.3 Migration guide:

1.- Check if sbt.version is set to 0.13.5 in your /project/build.properties file.

2.- Add sbt-web plugin in your project/plugins.sbt file: addSbtPlugin("com.typesafe.sbt" % "sbt-web" % "1.0.2")

3.- Enable SbtWeb plugin in your /build.sbt file like this lazy val root = (project in file(".")).enablePlugins(PlayJava, SbtWeb)

Let me know if this solved your problem.

Patricia answered 21/7, 2014 at 15:43 Comment(1)
Unfortunately, it didn't solve my problem even if I think I'm getting closer. I'll update my initial question to reflect what's new now.Quincyquindecagon
W
0

The problem you are having is nothing new, look here:

Static resources not found in (Selenium) JUnit test for Play 2.0 application executed from Eclipse

What i do to overcome this problem is simple (Eclipse example)

public abstract class RunInBrowserTest extends FluentTest {
    private static boolean isTestRunningInEclipse = true;
    static {
        if (System.getenv("PLAY_HOME") != null) {
            isTestRunningInEclipse = false;
        };
    }

    @BeforeClass
    public static void startApp() throws Exception {
        if (!isTestRunningInEclipse) {
            server = play.test.Helpers.testServer(port);
            server.start();
        }
    }
}

The "extends FluentTest" will allow you to have "goTo(url)" and "$(#blah).click" and the entire FluentLenium api available to you directly in your test class.

Also, make sure you have PLAY_HOME set in your environment variables, that's the trick actually.

If you want to enable running functional tests in Eclipse,

You first go to your console and type play run

Now you can just press the play button in Eclipse and your functional tests will run with no problem.

If you would like to get the javascript coverage of your functional tests check out the jscover-sbt-plugin here:

https://github.com/g00dnatur3/jscover-sbt-plugin

Cheers!

Wellwisher answered 20/7, 2014 at 12:55 Comment(2)
I do understand your theory but since I'm using Play 2.3.2 and the new Activator command line tool, I'm not sure of how achieve this with this setup. Perhaps you can enlighten me? I didn't install play directly, I rather used SBT to import it.Quincyquindecagon
You need to install play, meaning download it, unzup it and configure an envinroment variable PLAY_HOME to point to the place where you unzipped it. My solutions works with this setup.Wellwisher

© 2022 - 2024 — McMap. All rights reserved.