Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Guidance for Selenium 3 ?

    We're currently running CI automated tests (in Jenkins) with Selenium 2 (RemoteWebDriver) and an old version of Firefox (41.02).

    We're in the process of migrating to Selenium 3 with the following setup:
    Smartclient : SmartClient_v110p_2016-08-13_Pro.zip
    Selenium : v3.0.1, selenium-server-standalone-3.0.1.jar
    Firefox : 51.0.1
    Gecko driver : geckodriver-v0.13.0-win64
    Platform : Windows 10
    Java : version "1.8.0_121", Java(TM) SE Runtime Environment (build 1.8.0_121-b13)

    (We're using the Web driver from SmartClient_v110p_2016-08-13_Pro.zip)

    Tests that used to work OK now break with the new setup:
    Selenium attempts to locate an element "//DynamicForm[ID='meiLoginForm']/item[name=button]/button/" and we end up with the following stack trace:

    Code:
    org.openqa.selenium.UnsupportedCommandException: POST /session/f9694ba8-8783-4d95-b359-fdb53fa4449e/moveto did not match a known command Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700'
    System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
    Driver info: org.openqa.selenium.firefox.FirefoxDriver
    Capabilities [{rotatable=false, raisesAccessibilityExceptions=false, marionette=true, firefoxOptions={args=[], profile=UEsDBBQACAgIAK9pQUoAAAAAAAAAAAAAAAAHAAAAdXNlci5qc51WTW/bOBC991csfOoCGyJptpf2lKYpUKDYLGoEPRIUOZIYUySXQ1rxv9+hPmLHlqWkJ1vSDDnz5s2bSQiB+wDl+1URXEtPDEUJ3X9tK9YI04oADKwoDKjVX3+UwiD8+fld2nsqEcnGuxCzSw3CxLp/ZmS01XLB30JsXdiwOkbPfK2x3l3kz14gXhiwVazJ8cPHjy/dxoADCEU/CiLICOqbDhhvKBZpgNxiSMfhuobyeuKyDq4BjjJoH3lIlkfdZJfry+mLoiiQERz23t4ahzCdzWitXGuNE4rusqLKwNau/VWDXRNaGalpd09B+Yj5Mt44JcwC9rCNzhlkEIIL0ll05hDu0/RRV9ZZQq2BpoCw7h5xPhcERE1W0REXAmAi3EoKlMsgsJ73NdpumPNgOTxFCFaYXMw3M6jMZf2Z7PRlLRQq6C09CymBypksZY5EBy4hRJxE4rlSGr0RO1B3V5frfxwxJ5f272ljeqXu7S9tqb54dck0XeQefv4gj5UoXIqfCiPsZnXKuT4hLozhj0hg5Dh1D/1pbE9eE9xky9paRzAaIx3wX9LhHBMyDTY6sqGbRtZRcpkLswAYQYWhBpinGmbeJs9q6hpPZ/MWjMwdlEIu6eoo5Vxt27GGJU8FBmYJ2nL3QCZv1pHkcyvdzYYHMgUdd8QUA/SPYQxaRu6CrrTl3hktd9OuVEPDBuJQ8apE2eWyrMCSEK2mQbPQUo+yIfmZ0r/Iqg+D5ZfrVDS666t/u5c3XQCvE9nJY2bheW7loYq5gmR5Rur2TUtpth3ZT7vWlSXZwYXwHhlR1bW82HEFpUgmTmvPWCOJfiDbdLSn5Jml5sh9ahSStRh2rJfRzv7Dku3s0SMidw8/btj1wJIz0vootqIfJ7MKfFyKsaHmeXQad4DHbuLNXtLTNB8/n+cB4iJF97WXjbUkEuRWuLo8J7j9qdyKSI8ctmAX5PZgjN4TwxbDKYyTm04AX1UoBBFkPdBmaUQ3rCc3U6nxs0Ujkr+Kii/44gigoNW0+p4I1rFSXU+vSb2yX4zdRyyKaWF+D7ZnlGXYh5YXoYMpi90OsJ+ypECp0/VZ5DKzpoM4aB3Xj8VuX/pub/uV5uwmN8w33omVIhhtxfOsWCBJDTRaZQ1y87XXqy/9l7ePPiaU0jlisTAIJhfs312sjauq/HLY+Gal/6CXuoxvSRqpWwttMvusrupozkzGA9fxxt9RNj42Amtoh+yIuMp7Z4AjjPZrT15Tidi0bC7sPfu+NyUm368L+43kf1BLBwgXluUvugMAAOIMAABQSwECFAAUAAgICACvaUFKF5blL7oDAADiDAAABwAAAAAAAAAAAAAAAAAAAAAAdXNlci5qc1BLBQYAAAAAAQABADUAAADvAwAAAAA=}, appBuildId=20170125094131, version=, platform=XP, proxy={}, command_id=1, specificationLevel=0, acceptSslCerts=false, processId=4720, browserVersion=51.0.1, platformVersion=10.0, XULappId={ec8030f7-c20a-464f-9b0e-13a3a9e97384}, browserName=firefox, takesScreenshot=true, takesElementScreenshot=true, platformName=windows_nt, firefox_profile=UEsDBBQACAgIAK5pQUoAAAAAAAAAA...}]
    Session ID: f9694ba8-8783-4d95-b359-fdb53fa4449e
    Command duration or timeout: 76 milliseconds Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:49:13 -0700'
    System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
    Driver info: org.openqa.selenium.remote.RemoteWebDriver
    Capabilities [{rotatable=false, raisesAccessibilityExceptions=false, marionette=true, firefoxOptions={args=[], profile=UEsDBBQACAgIAK9pQUoAAAAAAAAAAAAAAAAHAAAAdXNlci5qc51WTW/bOBC991csfOoCGyJptpf2lKYpUKDYLGoEPRIUOZIYUySXQ1rxv9+hPmLHlqWkJ1vSDDnz5s2bSQiB+wDl+1URXEtPDEUJ3X9tK9YI04oADKwoDKjVX3+UwiD8+fld2nsqEcnGuxCzSw3CxLp/ZmS01XLB30JsXdiwOkbPfK2x3l3kz14gXhiwVazJ8cPHjy/dxoADCEU/CiLICOqbDhhvKBZpgNxiSMfhuobyeuKyDq4BjjJoH3lIlkfdZJfry+mLoiiQERz23t4ahzCdzWitXGuNE4rusqLKwNau/VWDXRNaGalpd09B+Yj5Mt44JcwC9rCNzhlkEIIL0ll05hDu0/RRV9ZZQq2BpoCw7h5xPhcERE1W0REXAmAi3EoKlMsgsJ73NdpumPNgOTxFCFaYXMw3M6jMZf2Z7PRlLRQq6C09CymBypksZY5EBy4hRJxE4rlSGr0RO1B3V5frfxwxJ5f272ljeqXu7S9tqb54dck0XeQefv4gj5UoXIqfCiPsZnXKuT4hLozhj0hg5Dh1D/1pbE9eE9xky9paRzAaIx3wX9LhHBMyDTY6sqGbRtZRcpkLswAYQYWhBpinGmbeJs9q6hpPZ/MWjMwdlEIu6eoo5Vxt27GGJU8FBmYJ2nL3QCZv1pHkcyvdzYYHMgUdd8QUA/SPYQxaRu6CrrTl3hktd9OuVEPDBuJQ8apE2eWyrMCSEK2mQbPQUo+yIfmZ0r/Iqg+D5ZfrVDS666t/u5c3XQCvE9nJY2bheW7loYq5gmR5Rur2TUtpth3ZT7vWlSXZwYXwHhlR1bW82HEFpUgmTmvPWCOJfiDbdLSn5Jml5sh9ahSStRh2rJfRzv7Dku3s0SMidw8/btj1wJIz0vootqIfJ7MKfFyKsaHmeXQad4DHbuLNXtLTNB8/n+cB4iJF97WXjbUkEuRWuLo8J7j9qdyKSI8ctmAX5PZgjN4TwxbDKYyTm04AX1UoBBFkPdBmaUQ3rCc3U6nxs0Ujkr+Kii/44gigoNW0+p4I1rFSXU+vSb2yX4zdRyyKaWF+D7ZnlGXYh5YXoYMpi90OsJ+ypECp0/VZ5DKzpoM4aB3Xj8VuX/pub/uV5uwmN8w33omVIhhtxfOsWCBJDTRaZQ1y87XXqy/9l7ePPiaU0jlisTAIJhfs312sjauq/HLY+Gal/6CXuoxvSRqpWwttMvusrupozkzGA9fxxt9RNj42Amtoh+yIuMp7Z4AjjPZrT15Tidi0bC7sPfu+NyUm368L+43kf1BLBwgXluUvugMAAOIMAABQSwECFAAUAAgICACvaUFKF5blL7oDAADiDAAABwAAAAAAAAAAAAAAAAAAAAAAdXNlci5qc1BLBQYAAAAAAQABADUAAADvAwAAAAA=}, appBuildId=20170125094131, version=, platform=XP, proxy={}, command_id=1, specificationLevel=0, acceptSslCerts=false, processId=4720, webdriver.remote.sessionid=d082667f-d070-4c4d-97e4-e3ee6c84f4f6, browserVersion=51.0.1, platformVersion=10.0, XULappId={ec8030f7-c20a-464f-9b0e-13a3a9e97384}, browserName=firefox, takesScreenshot=true, takesElementScreenshot=true, javascriptEnabled=true, platformName=windows_nt, cssSelectorsEnabled=true, firefox_profile=UEsDBBQACAgIAK5pQUoAAAAAAAAAA...}]
    Session ID: d082667f-d070-4c4d-97e4-e3ee6c84f4f6
    
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635)
    at org.openqa.selenium.remote.RemoteExecuteMethod.execute(RemoteExecuteMethod.java:35)
    at org.openqa.selenium.remote.RemoteMouse.mouseMove(RemoteMouse.java:97)
    at org.openqa.selenium.interactions.MoveToOffsetAction.perform(MoveToOffsetAction.java:41)
    at org.openqa.selenium.interactions.CompositeAction.perform(CompositeAction.java:50)
    at org.openqa.selenium.interactions.Actions.perform(Actions.java:373)
    at com.isomorphic.webdriver.ScActions.perform(ScActions.java:265)
    at com.isomorphic.webdriver.SmartClientWebDriver.internalClick(SmartClientWebDriver.java:791)
    at com.isomorphic.webdriver.SmartClientWebDriver.click(SmartClientWebDriver.java:818)
    at com.meicpg.test.selenium.ScElement.clickScElement(ScElement.java:685)
    at com.meicpg.test.selenium.ScElement.click(ScElement.java:71)
    at com.meicpg.test.selenium.pageobject.LoginPage.with(LoginPage.java:39)
    at com.meicpg.test.selenium.SeleniumBaseTest.openHomePage(SeleniumBaseTest.java:78)
    at com.meicpg.test.selenium.FapTest.test_deduction_write_TCM00614(FapTest.java:403)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at com.meicpg.test.selenium.SeleniumTestSupportRule$ScreenshotTestRule$1.evaluate(SeleniumTestSupportRule.java:193)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
    Caused by: org.openqa.selenium.UnsupportedCommandException: POST /session/f9694ba8-8783-4d95-b359-fdb53fa4449e/moveto did not match a known command Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700'
    System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
    Driver info: org.openqa.selenium.firefox.FirefoxDriver
    Capabilities [{rotatable=false, raisesAccessibilityExceptions=false, marionette=true, firefoxOptions={args=[], profile=UEsDBBQACAgIAK9pQUoAAAAAAAAAAAAAAAAHAAAAdXNlci5qc51WTW/bOBC991csfOoCGyJptpf2lKYpUKDYLGoEPRIUOZIYUySXQ1rxv9+hPmLHlqWkJ1vSDDnz5s2bSQiB+wDl+1URXEtPDEUJ3X9tK9YI04oADKwoDKjVX3+UwiD8+fld2nsqEcnGuxCzSw3CxLp/ZmS01XLB30JsXdiwOkbPfK2x3l3kz14gXhiwVazJ8cPHjy/dxoADCEU/CiLICOqbDhhvKBZpgNxiSMfhuobyeuKyDq4BjjJoH3lIlkfdZJfry+mLoiiQERz23t4ahzCdzWitXGuNE4rusqLKwNau/VWDXRNaGalpd09B+Yj5Mt44JcwC9rCNzhlkEIIL0ll05hDu0/RRV9ZZQq2BpoCw7h5xPhcERE1W0REXAmAi3EoKlMsgsJ73NdpumPNgOTxFCFaYXMw3M6jMZf2Z7PRlLRQq6C09CymBypksZY5EBy4hRJxE4rlSGr0RO1B3V5frfxwxJ5f272ljeqXu7S9tqb54dck0XeQefv4gj5UoXIqfCiPsZnXKuT4hLozhj0hg5Dh1D/1pbE9eE9xky9paRzAaIx3wX9LhHBMyDTY6sqGbRtZRcpkLswAYQYWhBpinGmbeJs9q6hpPZ/MWjMwdlEIu6eoo5Vxt27GGJU8FBmYJ2nL3QCZv1pHkcyvdzYYHMgUdd8QUA/SPYQxaRu6CrrTl3hktd9OuVEPDBuJQ8apE2eWyrMCSEK2mQbPQUo+yIfmZ0r/Iqg+D5ZfrVDS666t/u5c3XQCvE9nJY2bheW7loYq5gmR5Rur2TUtpth3ZT7vWlSXZwYXwHhlR1bW82HEFpUgmTmvPWCOJfiDbdLSn5Jml5sh9ahSStRh2rJfRzv7Dku3s0SMidw8/btj1wJIz0vootqIfJ7MKfFyKsaHmeXQad4DHbuLNXtLTNB8/n+cB4iJF97WXjbUkEuRWuLo8J7j9qdyKSI8ctmAX5PZgjN4TwxbDKYyTm04AX1UoBBFkPdBmaUQ3rCc3U6nxs0Ujkr+Kii/44gigoNW0+p4I1rFSXU+vSb2yX4zdRyyKaWF+D7ZnlGXYh5YXoYMpi90OsJ+ypECp0/VZ5DKzpoM4aB3Xj8VuX/pub/uV5uwmN8w33omVIhhtxfOsWCBJDTRaZQ1y87XXqy/9l7ePPiaU0jlisTAIJhfs312sjauq/HLY+Gal/6CXuoxvSRqpWwttMvusrupozkzGA9fxxt9RNj42Amtoh+yIuMp7Z4AjjPZrT15Tidi0bC7sPfu+NyUm368L+43kf1BLBwgXluUvugMAAOIMAABQSwECFAAUAAgICACvaUFKF5blL7oDAADiDAAABwAAAAAAAAAAAAAAAAAAAAAAdXNlci5qc1BLBQYAAAAAAQABADUAAADvAwAAAAA=}, appBuildId=20170125094131, version=, platform=XP, proxy={}, command_id=1, specificationLevel=0, acceptSslCerts=false, processId=4720, browserVersion=51.0.1, platformVersion=10.0, XULappId={ec8030f7-c20a-464f-9b0e-13a3a9e97384}, browserName=firefox, takesScreenshot=true, takesElementScreenshot=true, platformName=windows_nt, firefox_profile=UEsDBBQACAgIAK5pQUoAAAAAAAAAA...}]
    Session ID: f9694ba8-8783-4d95-b359-fdb53fa4449e
    Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:49:13 -0700'
    System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
    Driver info: driver.version: RemoteWebDriver
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:127)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:93)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:42)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:163)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:82)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601)
    at org.openqa.selenium.remote.RemoteExecuteMethod.execute(RemoteExecuteMethod.java:35)
    at org.openqa.selenium.remote.RemoteMouse.mouseMove(RemoteMouse.java:97)
    at org.openqa.selenium.support.events.internal.EventFiringMouse.mouseMove(EventFiringMouse.java:62)
    at org.openqa.selenium.remote.server.handler.interactions.MouseMoveToLocation.call(MouseMoveToLocation.java:57)
    at org.openqa.selenium.remote.server.handler.interactions.MouseMoveToLocation.call(MouseMoveToLocation.java:32)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:176)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    I couldn't find anything on the forum about Selenium 3.

    Is Selenium 3 supported with SmartClient 11 ?

    Thanks !

    #2
    Selenium 3 came out after SmartClient 11, so no, not officially supported. In theory, it's fully backwards compatible. In practice, obviously not.

    Once we've worked out what needs to be changed on our end, we may be able to backport support to 11.0.

    Comment


      #3
      Supporting Selenium 3 would require us to make potentially breaking changes to our existing WebDriver support and upgrade a number of Selenium dependencies we ship, in addition to the Selenium JAR itself. Right now, our suggestion is to downgrade to Firefox 45 ESR, which is under support and works with the JARs we ship for SC 11.0 - indeed it's what our automated tests are run against.

      Comment


        #4
        Thank you for the information about Firefox ESR.

        According to your guidance, we "downgraded" our setup to the following:

        Selenium: 2.53.1, isomorphic_webdriver_v110p_2016-07-08, selenium-server-standalone-2.53.1.jar
        Firefox 45 ESR (64bits) 45.7.0
        Java : version "jdk1.7.0_80"

        Elements that were NOT changed:
        Smartclient : v11.0p_2016-08-13/Pro Deployment - 2016-08-13 -- NOT CHANGED
        Platform: Windows 10 -- NOT CHANGED

        The problem we face is now different: on the login page, the "Login" button doesn't seem to be targeted at the appropriate location.

        Code:
        2017-02-02 11:41:21,349 DEBUG ScElement:667 - Call SmartClientWebDriver.waitForElementClickable() for 'By.scLocator: //DynamicForm[ID='meiLoginForm']/item[name=button]/button/' -- BEGIN
        2017-02-02 11:41:21,467 DEBUG ScElement:671 - Call SmartClientWebDriver.waitForElementClickable() for 'By.scLocator: //DynamicForm[ID='meiLoginForm']/item[name=button]/button/' -- END. Return value : true
        2017-02-02 11:41:21,467 DEBUG ScElement:683 - Call SmartClientWebDriver.click() for 'By.scLocator: //DynamicForm[ID='meiLoginForm']/item[name=button]/button/' -- BEGIN
        
        org.openqa.selenium.WebDriverException: Element is not clickable at point (936, 560). Other element would receive the click: <div id="isc_I" style="display:inline-block;box-sizing:border-box;max-width:100%;vertical-align:middle;overflow:hidden;text-overflow:ellipsis"></div> (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 54 milliseconds Build info: version: '2.53.1', revision: 'a36b8b1', time: '2016-06-30 17:37:03'
        System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
        Driver info: org.openqa.selenium.firefox.FirefoxDriver
        Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=45.7.0, platform=WINDOWS, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}] Session ID: 6906df71-c3b7-4ccf-a8ac-61306105d348
        Command duration or timeout: 84 milliseconds Build info: version: '2.53.1', revision: 'a36b8b1cd5757287168e54b817830adce9b0158d', time: '2016-06-30 19:26:09'
        System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 8.1', os.arch: 'amd64', os.version: '6.3', java.version: '1.7.0_80'
        Session ID: 79009ff0-dece-425b-90a6-529a27ba8438
        Driver info: org.openqa.selenium.remote.RemoteWebDriver
        Capabilities [{platform=WINDOWS, javascriptEnabled=true, acceptSslCerts=true, browserName=firefox, rotatable=false, locationContextEnabled=true, webdriver.remote.sessionid=79009ff0-dece-425b-90a6-529a27ba8438, version=45.7.0, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, webStorageEnabled=true, nativeEvents=false, applicationCacheEnabled=true, takesScreenshot=true}]
        
                        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
                        at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
                        at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
                        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
                        at org.openqa.selenium.remote.RemoteExecuteMethod.execute(RemoteExecuteMethod.java:35)
                        at org.openqa.selenium.remote.RemoteMouse.click(RemoteMouse.java:59)
                        at org.openqa.selenium.interactions.ClickAction.perform(ClickAction.java:37)
                        at org.openqa.selenium.interactions.CompositeAction.perform(CompositeAction.java:50)
                        at org.openqa.selenium.interactions.Actions.perform(Actions.java:373)
                        at com.isomorphic.webdriver.ScActions.perform(ScActions.java:265)
                        at com.isomorphic.webdriver.SmartClientWebDriver.internalClick(SmartClientWebDriver.java:791)
                        at com.isomorphic.webdriver.SmartClientWebDriver.click(SmartClientWebDriver.java:818)
                        at com.meicpg.test.selenium.ScElement.clickScElement(ScElement.java:685)
                        at com.meicpg.test.selenium.ScElement.click(ScElement.java:71)
                        at com.meicpg.test.selenium.pageobject.LoginPage.with(LoginPage.java:39)
                        at com.meicpg.test.selenium.SeleniumBaseTest.openHomePage(SeleniumBaseTest.java:78)
                        at com.meicpg.test.selenium.FapTest.test_deduction_write_TCM00614(FapTest.java:403)
                        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
                        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                        at java.lang.reflect.Method.invoke(Method.java:606)
                        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
                        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
                        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
                        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
                        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
                        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
                        at com.meicpg.test.selenium.SeleniumTestSupportRule$ScreenshotTestRule$1.evaluate(SeleniumTestSupportRule.java:191)
                        at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
                        at org.junit.rules.RunRules.evaluate(RunRules.java:20)
                        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
                        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
                        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
                        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
                        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
                        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
                        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
                        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
                        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
                        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
                        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
                        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
                        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
                        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
                        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
                        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                        at java.lang.reflect.Method.invoke(Method.java:606)
                        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
        Caused by: org.openqa.selenium.WebDriverException: Element is not clickable at point (936, 560). Other element would receive the click: <div id="isc_I" style="display:inline-block;box-sizing:border-box;max-width:100%;vertical-align:middle;overflow:hidden;text-overflow:ellipsis"></div> (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 54 milliseconds Build info: version: '2.53.1', revision: 'a36b8b1', time: '2016-06-30 17:37:03'
        System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_121'
        Driver info: org.openqa.selenium.firefox.FirefoxDriver
        Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=45.7.0, platform=WINDOWS, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}] Session ID: 6906df71-c3b7-4ccf-a8ac-61306105d348
        Build info: version: '2.53.1', revision: 'a36b8b1cd5757287168e54b817830adce9b0158d', time: '2016-06-30 19:26:09'
        System info: host: 'MTLDEVDAP', ip: '172.16.3.68', os.name: 'Windows 8.1', os.arch: 'amd64', os.version: '6.3', java.version: '1.7.0_80'
        Driver info: driver.version: RemoteWebDriver
                        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
                        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
                        at java.lang.reflect.Constructor.newInstance(Unknown Source)
                        at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
                        at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
                        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
                        at org.openqa.selenium.remote.RemoteExecuteMethod.execute(RemoteExecuteMethod.java:35)
                        at org.openqa.selenium.remote.RemoteMouse.click(RemoteMouse.java:59)
                        at org.openqa.selenium.support.events.internal.EventFiringMouse.click(EventFiringMouse.java:42)
                        at org.openqa.selenium.remote.server.handler.interactions.ClickInSession.call(ClickInSession.java:40)
                        at org.openqa.selenium.remote.server.handler.interactions.ClickInSession.call(ClickInSession.java:1)
                        at java.util.concurrent.FutureTask.run(Unknown Source)
                        at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:176)
                        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
                        at java.lang.Thread.run(Unknown Source)
        Using the "ruler_guides" add-on in Firefox, we took the following screenshots.

        Screenshot 1 shows the coordinates extracted from the stacktrace (936, 560): the "Login" button is NOT at that location.
        Click image for larger version

Name:	screenshot1.png
Views:	143
Size:	40.4 KB
ID:	242609

        Screenshot 2 shows the top-left coordinates of the "Login" button (approximately 900, 500).
        Click image for larger version

Name:	screenshot2.png
Views:	120
Size:	31.4 KB
ID:	242610

        What could explain the offset ?

        Thanks !

        Comment


          #5
          Note that you should never use SC JARs that mismatch the SmartClient release you're using. So you should be using the webdriver JAR that was bundled with the SmartClient v11.0p_2016-08-13 release, in your case. Also note that the shipped Selenium JARs for SC 11.0p are version 2.53.0, not 2.53.1. Not that there's any expected incompatibility, but since you want us to investigate misbehavior, please first try with the shipped configuration.

          Looking at your diagrams, note that Selenium will attempt to click on the center of a given element, so the x-ccoordinate in your top diagram is likely correct - there's just an unexpected offset in the y-coordinate.

          Comment


            #6
            We adjusted our setup to comply with your instructions:

            <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>2.53.0</version>
            </dependency>

            <dependency>
            <groupId>com.smartclient</groupId>
            <artifactId>isomorphic_webdriver</artifactId>
            <version>v110p_2016-08-13</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/isomorphic_webdriver.jar</systemPath>
            </dependency>


            We're running selenium-server-standalone-2.53.0.jar .

            Unfortunately, we're still getting the same problem.

            Can we enable some logging from the WebDriver to post additional info here ?

            Thanks !

            Comment


              #7
              Can you provide the code for your dialog? Any click actions can be omitted, and any data-dependent content can be replaced with the actual values present when the problem happens.

              Comment


                #8
                General context about our situation: we already have Jenkins run Selenium tests multiple times a day with the following setup:

                Smartclient : SmartClient_v110p_2016-08-13_Pro.zip
                Selenium :selenium-server-standalone-2.48.2.jar
                WebDriver : isomorphic_webdriver_v110p_2016-07-08 --- We're now aware that running a non-synced version of JavaScript code and WebDriver is not recommanded; but it has been running like this for months now.
                Firefox : 41.0.2

                On Jenkins, Selenium is started like this:
                java -jar selenium-server-standalone-2.48.2.jar -browserSideLog -ensureCleanSession -Dwebdriver.enable.native.events=1

                Here is the requested code. I might have given a bit more than expected, but I want to provide as much info as possible so we can find the solution.

                The problem happens as soon as we hit the app: it's our login page.

                I provided all the code in case you see something strange...

                Code:
                //-----------------------------
                RPCManager.addClassProperties
                ({
                    //-----------------------------
                    // Properties
                    //-----------------------------
                
                    /**
                     * Handle to login window which gets shown/hidden as needed.
                     *
                     * @field
                     * @type Window
                     * @default null
                     */
                    xyzCompanyLoginWindow : null,
                
                    /**
                     * Semaphore used to make sure that there is a single login dialog displayed at any given time.
                     * It's important to have a single login window drawn/displayed because:
                     *    - we do not want login windows to stack on top of each others.
                     *    - on successful login, all suspended transactions are resumed.
                     */
                    xyzCompanyLoginInProgressUsingDialog : false,
                
                
                    //-----------------------------
                    // Methods
                    //-----------------------------
                
                    //--------------------------------------------------------------------------------------------------------------------------------
                    /*
                     * Displays the 'Login' user interface.
                     *
                     * @inner
                     * [USER="45788"]param[/USER] {Object} transactionNum. This parameter is part of the signature in order to be compliant with the API but we de not
                     *                                 use it because we want ALL the transactions to be resumed on successful login.
                     * [USER="45788"]param[/USER] {RPCRequest} rpcRequest
                     * [USER="45788"]param[/USER] {RPCResponse} rpcResponse
                     * @return {void}
                     */
                    //--------------------------------------------------------------------------------------------------------------------------------
                    loginRequired : function(transactionNum, rpcRequest, rpcResponse)
                    {
                        if (RPCManager.xyzCompanyLoginInProgressUsingDialog)
                        {
                            // We do not want to have more than one login dialog at a time; this is why we "early bail-out".
                            return;
                        }
                
                        RPCManager.xyzCompanyLoginInProgressUsingDialog = true;
                
                        // load potentially saved login information from cookies
                
                        var savedUsername = Cookie.get(xyzCompanyLoginWindow.usernameCookieName);
                        var savedRemember = Cookie.get(xyzCompanyLoginWindow.rememberCookieName);
                
                        // create login layout
                
                        HLayout.create
                        ({
                            ID : 'xyzCompanyLoginLayout',
                            styleName : 'appView',
                            width : 425,
                            layoutMargin : 15,
                            membersMargin : 0,
                            members :
                            [
                                VLayout.create
                                ({
                                    width : 250,
                                    members :
                                    [
                                        Label.create
                                        ({
                                            ID: 'failedLoginMsgHolder',
                                            baseStyle : 'xyzCompanyLoginFailed',
                                            valign : 'top',
                                            height : 60,
                                            width : 250
                                        }),
                
                                        HLayout.create
                                        ({
                                            width : 40,
                                            height : 40,
                                            members :
                                            [
                                                // create login form
                
                                                DynamicForm.create
                                                ({
                                                    ID : 'xyzCompanyLoginForm',
                                                    autoFocus : true,
                                                    numCols : 2,
                                                    colWidths : [ 60, 120 ],
                                                    fields :
                                                        [
                                                            {
                                                                type : 'text', title : xyzCompanyStrings.get('login.username'), name: 'username',
                                                                    keyPress : function (item, form, keyName)
                                                                    {
                                                                        if (keyName == 'Enter')
                                                                        {
                                                                            form.focusInItem('password');
                                                                            return false;
                                                                        }
                                                                    }
                                                            },
                                                            {
                                                                type : 'password', title : xyzCompanyStrings.get('login.password'), name: 'password',
                                                                    keyPress : function (item, form, keyName)
                                                                    {
                                                                        if (keyName == 'Enter')
                                                                        {
                                                                            form.xyzCompanyLoginWindow.doLogin();
                                                                            return false;
                                                                        }
                                                                    }
                                                            },
                                                            {
                                                                type : 'checkbox', title : xyzCompanyStrings.get('login.rememberMe'), name : 'remember'
                                                            },
                                                            {
                                                                type : 'spacer', height : 5, colSpan : 2
                                                            },
                                                            {
                                                                type : 'button', name : 'button', title : xyzCompanyStrings.get('login.button.title'), colSpan : 2, width : 75,
                                                                    align : 'right', click : 'form.xyzCompanyLoginWindow.doLogin()'
                                                            },
                                                            {
                                                                type : 'spacer', height : 10, colSpan : 2
                                                            },
                                                            {
                                                                type : 'link', name : 'switch', canEdit : false, showTitle : false, colSpan : 2,
                                                                    align : 'left', linkTitle : xyzCompanyStrings.get('login.link.linkTitle'), visible : false, 
                                                                    click : 'xyzCompanyApplication.logout(true, true)', target : 'javascript'
                                                            }
                                                        ],
                                                    values :
                                                    {
                                                        username : savedUsername,
                                                        remember : savedRemember
                                                    }
                                                })
                                            ]
                                        })
                                    ]
                                }),
                
                                VLayout.create
                                ({
                                    align : 'left',
                                    layoutAlign : 'center',
                                    membersMargin : 0,
                                    width : 121,
                                    height : 128,
                                    members :
                                    [
                                        LayoutSpacer.create({ width : 1, height : 30 }),
                
                                        Img.create
                                        ({
                                            src : 'logo/trade-insight-logo-small.png', layoutAlign : 'center', imageType : 'normal',
                                                width : 161, height : 51, imageWidth : 161, imageHeight : 51
                                        }),
                
                                        LayoutSpacer.create({ width : 1, height : 15 }),
                
                                        // create activity feedback sink
                
                                        Img.create
                                        ({
                                            ID : 'xyzCompanyLoginInProgressImage', visibility : 'hidden',
                                                src : 'general/loading.gif', layoutAlign : 'center', imageType : 'normal',
                                                width : 32, height : 32, imageWidth : 32, imageHeight : 32
                                        })
                                    ]
                                })
                            ]
                        });
                
                        // create login window
                
                        this.xyzCompanyLoginWindow = xyzCompanyLoginWindow.create
                        ({
                            title : xyzCompanyStrings.get('login.screenTitle'),
                            autoCenter : true,
                            autoSize : true,
                            showCloseButton : false,
                            showMinimizeButton : false,
                            showShadow : false,
                            isModal : true,
                            items: [ xyzCompanyLoginLayout ]
                        });
                
                        xyzCompanyLoginForm.xyzCompanyLoginWindow = this.xyzCompanyLoginWindow;
                
                        // to support the display of Login when coming from landing page
                
                        if (Cookie.get(xyzCompanyApplication.lastUserNameCookieName))
                        {
                            // a user was previously logged in
                
                            // clear password field, make usename not editable, show the link to go back to login screen
                
                            xyzCompanyLoginForm.getItem('username').setValue(Cookie.get(xyzCompanyApplication.lastUserNameCookieName));
                            xyzCompanyLoginForm.getItem('username').setStateLayered(xyzCompanyLoginWindow.ACCESS_EDITABLE_USERNAME, false);
                            xyzCompanyLoginForm.getItem('switch').show();
                
                            xyzCompanyLoginForm.getItem('password').setValue(null);
                
                            xyzCompanyLoginForm.getItem('remember').hide();
                        }
                
                        if (!(this.xyzCompanyLoginWindow.isVisible() && this.xyzCompanyLoginWindow.isDrawn()))
                        {
                            failedLoginMsgHolder.setContents('');
                
                            // auto focus on either username or password, depending if username is already set
                
                            var autoFocusField = 'username';
                            if (xyzCompanyLoginForm.getValue('username'))
                                autoFocusField = 'password';
                
                            xyzCompanyLoginForm.delayCall('focusInItem', [ autoFocusField ]);
                        }
                
                        this.xyzCompanyLoginWindow.show();
                        this.xyzCompanyLoginWindow.bringToFront();
                    }
                });
                
                //--------------------------------------------------------------------------------------------------------------------------------
                /**
                 * Defines the window used for login purposes.
                 *
                 * @class Defines the login window
                 * @extends Window
                 * [USER="61157"]see[/USER] <a href="http://www.smartclient.com/docs/6.5.1/a/b/c/go.html#class..Window">Window</a> base class definition
                 */
                //--------------------------------------------------------------------------------------------------------------------------------
                
                var xyzCompanyLoginWindow = isc.defineClass('xyzCompanyLoginWindow', 'Window');
                
                //-----------------------------
                // Static class members
                //-----------------------------
                xyzCompanyLoginWindow.addClassProperties
                (
                    /** @lends xyzCompanyLoginWindow */
                {
                    //-----------------------------
                    // Constants
                    //-----------------------------
                
                    /**
                     * Cookie name which holds the user's username.
                     */
                    usernameCookieName : 'xyzCompanyLoginUserName',
                
                    /**
                     * Cookie name which holds the user's remember me status.
                     */
                    rememberCookieName : 'xyzCompanyLoginRemember',
                
                    /**
                     * Layered access token for 'editable username' state management
                     */
                    ACCESS_EDITABLE_USERNAME : 'ACCESS_EDITABLE_USERNAME'
                });
                
                //-----------------------------
                // Class members
                //-----------------------------
                xyzCompanyLoginWindow.addProperties
                (
                    /** @lends xyzCompanyLoginWindow.prototype */
                {
                    //-----------------------------
                    // Methods
                    //-----------------------------
                
                    //--------------------------------------------------------------------------------------------------------------------------------
                    /**
                     *  Submits the form fields to the Spring Security login servlet on the server.
                     *
                     * @return {void}
                     */
                    //--------------------------------------------------------------------------------------------------------------------------------
                    doLogin : function()
                    {
                        // disable login button while login is in progress
                
                        xyzCompanyLoginInProgressImage.show();
                        xyzCompanyLoginForm.getItem('button').setDisabledLayered('LOGIN_IN_PROGRESS');
                
                        // remember-me management
                
                        var remember = xyzCompanyLoginForm.getValue('remember');
                        if (remember == true || remember == 'true')
                        {
                            // update cookie information (cookie expiration is far out in the future)
                
                            var expiration = xyzCompanyDateUtils.getDate(2050, 01, 01);
                
                            Cookie.set(xyzCompanyLoginWindow.usernameCookieName,
                                xyzCompanyLoginForm.getValue('username'), '/', null, expiration);
                
                            Cookie.set(xyzCompanyLoginWindow.rememberCookieName,
                                xyzCompanyLoginForm.getValue('remember'), '/', null, expiration);
                        }
                        else
                        {
                            // clear cookie information
                
                            Cookie.clear(xyzCompanyLoginWindow.usernameCookieName, '/', null);
                            Cookie.clear(xyzCompanyLoginWindow.rememberCookieName, '/', null);
                        }
                
                        // actual login request to server
                
                        isc.RPCManager.sendRequest
                        ({
                            // let the RPCManager know not to delay this request and to discard this
                            // request/response pair if the auth attempt fails.
                
                            containsCredentials: true,
                            actionURL: isc.RPCManager.credentialsURL,
                            useSimpleHttp: true,
                            showPrompt: false,
                            params :
                            {
                                j_username : xyzCompanyLoginForm.getValue('username'),
                                j_password : xyzCompanyLoginForm.getValue('password')
                            },
                            callback : this.getID() + '.loginReply(rpcResponse)'
                        });
                    },
                
                    //--------------------------------------------------------------------------------------------------------------------------------
                    /**
                     *  Called upon server reply from Spring Security login servlet.
                     *
                     * [USER="45788"]param[/USER] {RPCResponse} rpcResponse
                     * @return {void}
                     */
                    //--------------------------------------------------------------------------------------------------------------------------------
                    loginReply : function(rpcResponse)
                    {
                        xyzCompanyLoginInProgressImage.hide();
                        xyzCompanyLoginForm.getItem('button').setEnabledLayered('LOGIN_IN_PROGRESS');
                
                        if (rpcResponse.status == isc.RPCResponse.STATUS_SUCCESS)
                        {
                            // hide login window
                
                            this.hide();
                
                            // Replace login dialog with generic "hold on" dialog so the user is aware there's something going on
                            // even though nothing is "in his face".
                            xyzCompanyApplication.showPrompt();
                            
                            // Display the user's password expiration notice
                            xyzCompanyUtils.displayNotification('PasswordExpirationNotice', 'global.message.expirePasswordWarning.title');
                
                            // if this loginReply() invocation was not initiated from a loginXml interface server fetch, fetch loginXml interface
                            // from server to have version/faps/resources/etc information refreshed ... prior to resuming suspended AJAX call
                
                            if (xyzCompanyApplication._loginInProgress)
                                this.resumeSuspendedAjaxCalls();
                            else
                            {
                                var self = this;
                
                                xyzCompanyApplication.initializeContext(
                                    function()
                                    {
                                        isc.clearPrompt();
                                        self.resumeSuspendedAjaxCalls();
                                    })
                            }
                
                            return;
                        }
                
                        // if we get to this point, login has failed
                
                        failedLoginMsgHolder.setContents(xyzCompanyStrings.get('login.failed'));
                
                        // Now that the error msg has been displayed, we also clear the password field so the previously submitted password is not available.
                        xyzCompanyLoginForm.clearValue('password');
                
                        xyzCompanyLoginForm.delayCall('focusInItem', [ 'username' ]);
                    },
                
                    //--------------------------------------------------------------------------------------------------------------------------------
                    resumeSuspendedAjaxCalls : function()
                    {
                        RPCManager.xyzCompanyLoginInProgressUsingDialog = false;
                
                        // resubmits all transactions that we previously delayed in loginRequired.  We do
                        // this on a delay so the this.hide() renders immediately
                
                        isc.RPCManager.delayCall("resendTransaction");  // We do not provide the transaction to resume; we assume all the transactions must be resumed
                
                        // reset Ajax transaction marker following succesfull login (required for relogin feature)
                
                        isc.xyzCompanyIsAjaxRequest = true;
                    }
                });
                Thanks !

                Comment


                  #9
                  Your example doesn't define xyzCompanyStrings.

                  Comment


                    #10
                    Sorry about that; my Find+Replace to make the snippet anonymous got too broad... :-(

                    xyzCompanyStrings.get(<key>) is basically a module that receives a key and returns a localized string.

                    Comment


                      #11
                      Can you provide repro code that has the English localizations for all of those lookups - including any others if there's more than xyzCompanyStrings? If there is any dependence on the text width, etc., that may not reproduce using the "key values" Ideally, we want code that will generate what you've captured in the snapshot.

                      Comment


                        #12
                        Instead of providing an implementation for xyzCompanyStrings, I re-worked my example to use strings directly into it.

                        Here it is:
                        Code:
                        //-----------------------------
                        RPCManager.addClassProperties
                        ({
                            //-----------------------------
                            // Properties
                            //-----------------------------
                        
                            /**
                             * Handle to login window which gets shown/hidden as needed.
                             *
                             * @field
                             * @type Window
                             * @default null
                             */
                            xyzCompanyLoginWindow : null,
                        
                            /**
                             * Semaphore used to make sure that there is a single login dialog displayed at any given time.
                             * It's important to have a single login window drawn/displayed because:
                             *    - we do not want login windows to stack on top of each others.
                             *    - on successful login, all suspended transactions are resumed.
                             */
                            xyzCompanyLoginInProgressUsingDialog : false,
                        
                        
                            //-----------------------------
                            // Methods
                            //-----------------------------
                        
                            //--------------------------------------------------------------------------------------------------------------------------------
                            /*
                             * Displays the 'Login' user interface.
                             *
                             * @inner
                             * param {Object} transactionNum. This parameter is part of the signature in order to be compliant with the API but we de not
                             *                                 use it because we want ALL the transactions to be resumed on successful login.
                             * param {RPCRequest} rpcRequest
                             * param {RPCResponse} rpcResponse
                             * @return {void}
                             */
                            //--------------------------------------------------------------------------------------------------------------------------------
                            loginRequired : function(transactionNum, rpcRequest, rpcResponse)
                            {
                                if (RPCManager.xyzCompanyLoginInProgressUsingDialog)
                                {
                                    // We do not want to have more than one login dialog at a time; this is why we "early bail-out".
                                    return;
                                }
                        
                                RPCManager.xyzCompanyLoginInProgressUsingDialog = true;
                        
                                // load potentially saved login information from cookies
                        
                                var savedUsername = Cookie.get(xyzCompanyLoginWindow.usernameCookieName);
                                var savedRemember = Cookie.get(xyzCompanyLoginWindow.rememberCookieName);
                        
                                // create login layout
                        
                                HLayout.create
                                ({
                                    ID : 'xyzCompanyLoginLayout',
                                    styleName : 'appView',
                                    width : 425,
                                    layoutMargin : 15,
                                    membersMargin : 0,
                                    members :
                                    [
                                        VLayout.create
                                        ({
                                            width : 250,
                                            members :
                                            [
                                                Label.create
                                                ({
                                                    ID: 'failedLoginMsgHolder',
                                                    baseStyle : 'xyzCompanyLoginFailed',
                                                    valign : 'top',
                                                    height : 60,
                                                    width : 250
                                                }),
                        
                                                HLayout.create
                                                ({
                                                    width : 40,
                                                    height : 40,
                                                    members :
                                                    [
                                                        // create login form
                        
                                                        DynamicForm.create
                                                        ({
                                                            ID : 'xyzCompanyLoginForm',
                                                            autoFocus : true,
                                                            numCols : 2,
                                                            colWidths : [ 60, 120 ],
                                                            fields :
                                                                [
                                                                    {
                                                                        type : 'text', title : 'Username', name: 'username',
                                                                            keyPress : function (item, form, keyName)
                                                                            {
                                                                                if (keyName == 'Enter')
                                                                                {
                                                                                    form.focusInItem('password');
                                                                                    return false;
                                                                                }
                                                                            }
                                                                    },
                                                                    {
                                                                        type : 'password', title : 'Password', name: 'password',
                                                                            keyPress : function (item, form, keyName)
                                                                            {
                                                                                if (keyName == 'Enter')
                                                                                {
                                                                                    form.xyzCompanyLoginWindow.doLogin();
                                                                                    return false;
                                                                                }
                                                                            }
                                                                    },
                                                                    {
                                                                        type : 'checkbox', title : 'Remember Me', name : 'remember'
                                                                    },
                                                                    {
                                                                        type : 'spacer', height : 5, colSpan : 2
                                                                    },
                                                                    {
                                                                        type : 'button', name : 'button', title : 'Login', colSpan : 2, width : 75,
                                                                            align : 'right', click : 'form.xyzCompanyLoginWindow.doLogin()'
                                                                    },
                                                                    {
                                                                        type : 'spacer', height : 10, colSpan : 2
                                                                    },
                                                                    {
                                                                        type : 'link', name : 'switch', canEdit : false, showTitle : false, colSpan : 2,
                                                                            align : 'left', linkTitle : 'Log in as a different user', visible : false, 
                                                                            click : 'xyzCompanyApplication.logout(true, true)', target : 'javascript'
                                                                    }
                                                                ],
                                                            values :
                                                            {
                                                                username : savedUsername,
                                                                remember : savedRemember
                                                            }
                                                        })
                                                    ]
                                                })
                                            ]
                                        }),
                        
                                        VLayout.create
                                        ({
                                            align : 'left',
                                            layoutAlign : 'center',
                                            membersMargin : 0,
                                            width : 121,
                                            height : 128,
                                            members :
                                            [
                                                LayoutSpacer.create({ width : 1, height : 30 }),
                        
                                                Img.create
                                                ({
                                                    src : 'logo/trade-insight-logo-small.png', layoutAlign : 'center', imageType : 'normal',
                                                        width : 161, height : 51, imageWidth : 161, imageHeight : 51
                                                }),
                        
                                                LayoutSpacer.create({ width : 1, height : 15 }),
                        
                                                // create activity feedback sink
                        
                                                Img.create
                                                ({
                                                    ID : 'xyzCompanyLoginInProgressImage', visibility : 'hidden',
                                                        src : 'general/loading.gif', layoutAlign : 'center', imageType : 'normal',
                                                        width : 32, height : 32, imageWidth : 32, imageHeight : 32
                                                })
                                            ]
                                        })
                                    ]
                                });
                        
                                // create login window
                        
                                this.xyzCompanyLoginWindow = xyzCompanyLoginWindow.create
                                ({
                                    title : 'XYZ ABC Retail - Login',
                                    autoCenter : true,
                                    autoSize : true,
                                    showCloseButton : false,
                                    showMinimizeButton : false,
                                    showShadow : false,
                                    isModal : true,
                                    items: [ xyzCompanyLoginLayout ]
                                });
                        
                                xyzCompanyLoginForm.xyzCompanyLoginWindow = this.xyzCompanyLoginWindow;
                        
                                // to support the display of Login when coming from landing page
                        
                                if (Cookie.get(xyzCompanyApplication.lastUserNameCookieName))
                                {
                                    // a user was previously logged in
                        
                                    // clear password field, make usename not editable, show the link to go back to login screen
                        
                                    xyzCompanyLoginForm.getItem('username').setValue(Cookie.get(xyzCompanyApplication.lastUserNameCookieName));
                                    xyzCompanyLoginForm.getItem('username').setStateLayered(xyzCompanyLoginWindow.ACCESS_EDITABLE_USERNAME, false);
                                    xyzCompanyLoginForm.getItem('switch').show();
                        
                                    xyzCompanyLoginForm.getItem('password').setValue(null);
                        
                                    xyzCompanyLoginForm.getItem('remember').hide();
                                }
                        
                                if (!(this.xyzCompanyLoginWindow.isVisible() && this.xyzCompanyLoginWindow.isDrawn()))
                                {
                                    failedLoginMsgHolder.setContents('');
                        
                                    // auto focus on either username or password, depending if username is already set
                        
                                    var autoFocusField = 'username';
                                    if (xyzCompanyLoginForm.getValue('username'))
                                        autoFocusField = 'password';
                        
                                    xyzCompanyLoginForm.delayCall('focusInItem', [ autoFocusField ]);
                                }
                        
                                this.xyzCompanyLoginWindow.show();
                                this.xyzCompanyLoginWindow.bringToFront();
                            }
                        });
                        
                        //--------------------------------------------------------------------------------------------------------------------------------
                        /**
                         * Defines the window used for login purposes.
                         *
                         * @class Defines the login window
                         * @extends Window
                         * see <a href="http://www.smartclient.com/docs/6.5.1/a/b/c/go.html#class..Window">Window</a> base class definition
                         */
                        //--------------------------------------------------------------------------------------------------------------------------------
                        
                        var xyzCompanyLoginWindow = isc.defineClass('xyzCompanyLoginWindow', 'Window');
                        
                        //-----------------------------
                        // Static class members
                        //-----------------------------
                        xyzCompanyLoginWindow.addClassProperties
                        (
                            /** @lends xyzCompanyLoginWindow */
                        {
                            //-----------------------------
                            // Constants
                            //-----------------------------
                        
                            /**
                             * Cookie name which holds the user's username.
                             */
                            usernameCookieName : 'xyzCompanyLoginUserName',
                        
                            /**
                             * Cookie name which holds the user's remember me status.
                             */
                            rememberCookieName : 'xyzCompanyLoginRemember',
                        
                            /**
                             * Layered access token for 'editable username' state management
                             */
                            ACCESS_EDITABLE_USERNAME : 'ACCESS_EDITABLE_USERNAME'
                        });
                        
                        //-----------------------------
                        // Class members
                        //-----------------------------
                        xyzCompanyLoginWindow.addProperties
                        (
                            /** @lends xyzCompanyLoginWindow.prototype */
                        {
                            //-----------------------------
                            // Methods
                            //-----------------------------
                        
                            //--------------------------------------------------------------------------------------------------------------------------------
                            /**
                             *  Submits the form fields to the Spring Security login servlet on the server.
                             *
                             * @return {void}
                             */
                            //--------------------------------------------------------------------------------------------------------------------------------
                            doLogin : function()
                            {
                                // disable login button while login is in progress
                        
                                xyzCompanyLoginInProgressImage.show();
                                xyzCompanyLoginForm.getItem('button').setDisabledLayered('LOGIN_IN_PROGRESS');
                        
                                // remember-me management
                        
                                var remember = xyzCompanyLoginForm.getValue('remember');
                                if (remember == true || remember == 'true')
                                {
                                    // update cookie information (cookie expiration is far out in the future)
                        
                                    var expiration = xyzCompanyDateUtils.getDate(2050, 01, 01);
                        
                                    Cookie.set(xyzCompanyLoginWindow.usernameCookieName,
                                        xyzCompanyLoginForm.getValue('username'), '/', null, expiration);
                        
                                    Cookie.set(xyzCompanyLoginWindow.rememberCookieName,
                                        xyzCompanyLoginForm.getValue('remember'), '/', null, expiration);
                                }
                                else
                                {
                                    // clear cookie information
                        
                                    Cookie.clear(xyzCompanyLoginWindow.usernameCookieName, '/', null);
                                    Cookie.clear(xyzCompanyLoginWindow.rememberCookieName, '/', null);
                                }
                        
                                // actual login request to server
                        
                                isc.RPCManager.sendRequest
                                ({
                                    // let the RPCManager know not to delay this request and to discard this
                                    // request/response pair if the auth attempt fails.
                        
                                    containsCredentials: true,
                                    actionURL: isc.RPCManager.credentialsURL,
                                    useSimpleHttp: true,
                                    showPrompt: false,
                                    params :
                                    {
                                        j_username : xyzCompanyLoginForm.getValue('username'),
                                        j_password : xyzCompanyLoginForm.getValue('password')
                                    },
                                    callback : this.getID() + '.loginReply(rpcResponse)'
                                });
                            },
                        
                            //--------------------------------------------------------------------------------------------------------------------------------
                            /**
                             *  Called upon server reply from Spring Security login servlet.
                             *
                             * param {RPCResponse} rpcResponse
                             * @return {void}
                             */
                            //--------------------------------------------------------------------------------------------------------------------------------
                            loginReply : function(rpcResponse)
                            {
                                xyzCompanyLoginInProgressImage.hide();
                                xyzCompanyLoginForm.getItem('button').setEnabledLayered('LOGIN_IN_PROGRESS');
                        
                                if (rpcResponse.status == isc.RPCResponse.STATUS_SUCCESS)
                                {
                                    // hide login window
                        
                                    this.hide();
                        
                                    // Replace login dialog with generic "hold on" dialog so the user is aware there's something going on
                                    // even though nothing is "in his face".
                                    xyzCompanyApplication.showPrompt();
                                    
                                    // Display the user's password expiration notice
                                    xyzCompanyUtils.displayNotification('PasswordExpirationNotice', 'global.message.expirePasswordWarning.title');
                        
                                    // if this loginReply() invocation was not initiated from a loginXml interface server fetch, fetch loginXml interface
                                    // from server to have version/faps/resources/etc information refreshed ... prior to resuming suspended AJAX call
                        
                                    if (xyzCompanyApplication._loginInProgress)
                                        this.resumeSuspendedAjaxCalls();
                                    else
                                    {
                                        var self = this;
                        
                                        xyzCompanyApplication.initializeContext(
                                            function()
                                            {
                                                isc.clearPrompt();
                                                self.resumeSuspendedAjaxCalls();
                                            })
                                    }
                        
                                    return;
                                }
                        
                                // if we get to this point, login has failed
                        
                                failedLoginMsgHolder.setContents('Your login attempt has failed. The username or password may be incorrect. Please contact the administrator at your company for help.');
                        
                                // Now that the error msg has been displayed, we also clear the password field so the previously submitted password is not available.
                                xyzCompanyLoginForm.clearValue('password');
                        
                                xyzCompanyLoginForm.delayCall('focusInItem', [ 'username' ]);
                            },
                        
                            //--------------------------------------------------------------------------------------------------------------------------------
                            resumeSuspendedAjaxCalls : function()
                            {
                                RPCManager.xyzCompanyLoginInProgressUsingDialog = false;
                        
                                // resubmits all transactions that we previously delayed in loginRequired.  We do
                                // this on a delay so the this.hide() renders immediately
                        
                                isc.RPCManager.delayCall("resendTransaction");  // We do not provide the transaction to resume; we assume all the transactions must be resumed
                        
                                // reset Ajax transaction marker following succesfull login (required for relogin feature)
                        
                                isc.xyzCompanyIsAjaxRequest = true;
                            }
                        });
                        Here are the 2 styles referred in the snippet:
                        .appView {
                        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#EFF3FC', endColorstr='#F9FAF0'); /* for IE */
                        background: -webkit-gradient(linear, left top, left bottom, from(#EFF3FC), to(#F9FAF0)); /* for webkit browsers */
                        background: -moz-linear-gradient(top, #EFF3FC, #F9FAF0); /* for firefox 3.6+ */
                        background-image: -ms-linear-gradient(top, #EFF3FC, #F9FAF0); /* for IE10+ */

                        border: 1px solid #C9DAEA;
                        border-top: 1px solid #FAFAFA;
                        }

                        .xyzCompanyLoginFailed
                        {
                        font-size: 8pt;
                        color: #990000;
                        }

                        Let me know if you need something more.

                        Thanks !

                        Comment


                          #13
                          If you guys are available for a screen sharing session; I'm all in.

                          Please contact me off he forum so we can arrange something; I 've got a feeling that investigation would be much simpler and more efficient. ;-)

                          Thank you !

                          Comment


                            #14
                            A "screen sharing session" would require special paid support. We'll see if we can work with the latest code you provided. Do you know whether your configuration has the same issue on other OSes - Linux / Windows 7?

                            Comment


                              #15
                              We've fixed one issue that we saw lead to a crash in our locator code while working with your example. The fix has been applied to SmartClient 11.0p and newer branches, and will be in the nightly builds dated 2-8-2017 and beyond. We didn't see any issue generating and using a locator to the "Login" button in FF45 ESR in WIndows 10 using your example with that fix in place, so please try to install the patched release and see if it resolves the issue.

                              Comment

                              Working...
                              X