-->

assets are not loaded in functional test mode

2019-01-25 13:16发布

问题:

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?

回答1:

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!



回答2:

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.



回答3:

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!