Hi,

if you have time to provide and test such a contribution, it'd be most welcome. If so, please raise a JIRA issue and add a link to a pull request in github.

Yes, it'd be better to separate the thread management functionality into different class(es) that can then be easily reused in steps classes (e.g. annotated per-story or per-scenario).

Equally, this thread management functionality could also be used by the implementations of the providers.

Thanks for your input and help.

Cheers

On 31/07/2014 20:07, Emanuel Campolo wrote:
Hi Mauro ,

Im not experiencing any articular issue but it's not a good idea to have those instances attached to a thread since memory leaks are plausible. Moreover, if you inspect those FluentWebDriver instances they keep the instance of the WebDriver object even after the end() method is called. (I think it is something that has to do with the garbage collector and weak references). We should also consider the scenario where multiple threads create a large amount of page objects. The number of page objects and therefore, the FluentWebDriver instances would increase considerably.

A FluentLifecycleSteps class is a good idea. Also, the provider could have a reference to a class thats if responsible to keep track of the threads locals instances that are created. This class could use the unique thread id value in a map. Maybe the provider is doing too much. We should delegate how we store resources (either WebDriver of FluentWebDriver instances) and how we eliminate them.


2014-07-31 14:12 GMT-03:00 Mauro Talevi <mauro.tal...@aquilonia.org <mailto:mauro.tal...@aquilonia.org>>:

    Hi Emanuel,

    thanks for providing this example.   The one WebDriver instance is
    correctly managed in the WebDriverProvider.end() method.

    The FluentWebDriver instances are not managed in the same way -
    they are not WebDriver instances  and there is no lifecycle
    management.   There is an instance created for each page, each
    using the same WebDriver instance as delegate.

    I'm not sure this constitutes a memory leak, simply that the
    instances are not removed at the end of the story execution.   But
    that could easily apply to other objects as well.

    Are you experiencing any specific issues as a consequence of
    this?    If so, I'd would add a FluentLifecycleSteps class method
    that finds the ThreadLocal instances of FluentWebDriver and
    nullifies them, and we can annotate it @AfterStory.

    Cheers


    On 30/07/2014 21:39, Emanuel Campolo wrote:
    Hi Mauro,

    I could reproduce the memory leak. To do that, I created a
    project from the jbehave-web archetype and made the some
    modifications in order to get some logs.
    I also refactored some of the page objects since the default test
    cases had some errors due to etsy home page modifications.

    This is the project:
    
https://github.com/emacampolo/etsy-jbehave/tree/jbehave-web-possible-memory-leak

    And this is the class that prints the logs:
    
https://github.com/emacampolo/etsy-jbehave/blob/jbehave-web-possible-memory-leak/src/main/java/org/jbehave/tutorials/etsy/steps/JournaledStoriesSteps.java

    Below you can find the output (I print all the ThreadLocal
    instances that are subclasses of WebDriver or FluentWebDriver).

    *Narrative:*
    *In order to show the browsing cart functionality*
    *As a user*
    *I want to browse in a gallery*
    *Scenario: Browsing around the site for items*
    ****************************************
    *LOGGING BEFORE SCENARIO*
    *
    *
    *Thread name: main*
    *DoublyOverriddenFirefoxDriver: firefox on LINUX
    (eea68437-dfb6-4783-9ebf-d3b2c95c9f28)*
    ****************************************
    *Given I am on etsy.com <http://etsy.com>*
    *When I want to browse through an art gallery*
    *When I want to buy something from etsy.com <http://etsy.com>*
    *When I want to browse the Art*
    *When I choose the first art gallery*
    *Then results will be displayed in the gallery*
    *
    *
    ****************************************
    *LOGGING BEFORE CALLING END()*
    *
    *
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@1570e827*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@27996370*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@474f625f*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@2cc36f8c*
    *Thread name: main*
    *DoublyOverriddenFirefoxDriver: firefox on LINUX
    (eea68437-dfb6-4783-9ebf-d3b2c95c9f28)*
    ****************************************
    *
    *
    *[INFO] 2 stories excluded by filter: +category browsing*
    *
    *
    *
    *
    *(AfterStories)*
    ****************************************
    *LOGGING AFTER STORIES*
    *
    *
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@1570e827*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@27996370*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@474f625f*
    *Thread name: main*
    *org.seleniumhq.selenium.fluent.FluentWebDriver@2cc36f8c*
    ****************************************

    As you can see, by the time the suite is over, there are 4
    FluentWebDriver instances (one for each page object that is
    created) attached to the current thread.
    On the other hand, you may notice that the
    *DoublyOverriddenFirefoxDriver *is removed correctly.
    There are a couple of approaches to solve this. First, let's
    validate this issue.


    Note: If you want to run it, please use the following filter
    since the other test cases seems not to be working

    mvn clean install -Dmeta.filter="+category browsing"


    2014-07-30 13:47 GMT-03:00 Mauro Talevi
    <mauro.tal...@aquilonia.org <mailto:mauro.tal...@aquilonia.org>>:

        It's your right to use alternative implementations, but at
        least the interfaces should be the same and the maven
        dependencies declared.

        If you find there's a bug in an implementation, the best way
        to address it is to provide a same project that reproduces it
        and perhaps a patch for it.

        On 30/07/2014 18:21, Emanuel Campolo wrote:

        Please dont get me wrong. I do want to help. I've copied
        some classes because i found out that I could have memory
        leak issues using the FluentWebDriverPage.
        I will send you some logs using a newly created project with
        the jbehave-web archetype.

        On Jul 30, 2014 1:09 PM, "Mauro Talevi"
        <mauro.tal...@aquilonia.org
        <mailto:mauro.tal...@aquilonia.org>> wrote:

            It seems to me that you're not even using jbehave-web.
            You've copied selected classes from it into your project
            and using them in a way which is different from
            jbehave-web, e.g. introducing another factory abstraction.

            If you'd help on using jbehave-web, including resolving
            issues with its current implementation, we'd be happy to
            help.

            If you're writing your own framework, then we can't help.

            Cheers

            On 30/07/2014 17:52, Emanuel Campolo wrote:
            Hi Mauro, thanks for taking your time to reply.

            I mentioned PerStoryWebDriverSteps as an example of how
            the framework cleans up the resources. In this case,
            when the end() method is invoked, the
            ThreadLocal<WebDriver> instance associated with the
            current thread is removed but, if you'd used a
            FluentWebDriverPage instead of a WebDriverPage, a
            ThreadLocal<FluentWebDriver> will not be eliminated
            from the list of thread locals.
            Even though im not using the jbehave-core for running
            my tests, Im coding a lightweight selenium-based
            framework using testng and the jbehave-web project.
            As you can see below, I had to re write some of the
            classes to solve this issue where resources are not
            being removed by the DelegatingWebDriverProvider
            (javadoc and reference to jbehave-web will be added):

            
https://github.com/emacampolo/hatchery/blob/master/src/main/java/com/hatchery/core/DefaultWebDriverProvider.java
            
https://github.com/emacampolo/hatchery/blob/master/src/main/java/com/hatchery/core/pages/FluentWebDriverPage.java

            This is where I invoke the end() method
            
https://github.com/emacampolo/hatchery/blob/master/src/main/java/com/hatchery/core/Suite.java


            2014-07-30 12:06 GMT-03:00 Mauro Talevi
            <mauro.tal...@aquilonia.org
            <mailto:mauro.tal...@aquilonia.org>>:

                Hi,

                the FluentWebDriverPage is simply a fluent-based
                facade using a FluentWebDriver.   The underlying
                 WebDriverProvider is the same as a non-fluent page
                and is injected in the constructor.

                The PerStoryWebDriverSteps should use exactly the
                same underlying WebDriverProvider (autowired via
                some dependency-injection mechanism), so if the
                provider end() method is invoked you shouldn't need
                to do anything else.

                Are you experiencing or noticing a particular
                problem?  If so, could you share a project that
                reproduced it?

                Cheers


                On 29/07/2014 19:14, Emanuel Campolo wrote:

                    Hi all !

                    I've added the jbehave-web module to a personal
                    project where I use testng. I'm using the
                    FirefoxWebDriverProvider to manage the
                    webdriver instances, taking advantage of the
                    ThreadLocal for multithreaded tests.
                    My question is, even though I call the end()
                    method every time a test completes to remove
                    the driver assigned to the current thread, i
                    don't know how to the same thing to the
                    FluentWebDriver (a thread local variable that
                    the FluentWebDriverPage has).

                    I noticed that , for example, the
                    PerStoryWebDriverSteps only executes
                    driverProvider.end() but as in mentioned above,
                     i didn't find any clean up for the
                    FluentWebDriver instances that
                    FluentWebDriverPage creates.

                    Thanks in advance :)



                
---------------------------------------------------------------------
                To unsubscribe from this list, please visit:

                http://xircles.codehaus.org/manage_email









Reply via email to