After do |scenario|
if scenario.failed?
Dir::mkdir('screenshots') if not File.directory?('screenshots')
screenshot = "./screenshots/FAILED_#{scenario.name.gsub(' ','_').gsub(/[^0-9A-Za-z_]/, '')}.png"
@browser.driver.save_screenshot(screenshot)
embed screenshot, 'image/png'
end
@browser.close
end
But it will create the file but nothing gets populated, and this exception comes up:
No connection could be made because the target machine actively refused it. - connect(2)
Well I pinpointed the error - it's the fact that the browser is closed before I made the call to take the screenshot. Put the browser close in a finally (ensure) block to make sure it's closed off.
Friday, 2 November 2012
Ruby/Watir/Cucumber: Taking a screenshot error: No connection could be made because the target machine actively refused it. - connect(2)
I was tasked with investigating a framework that lets QAs and Devs work together so we can get a functional test suite up. One of the tasks is to ensure we can capture screenshots on error so we can troubleshoot it. Here's my original code:
Monday, 29 October 2012
Ubuntu 12.10 - Unable to suspend
I'm having an issue where after I upgraded to the latest version 12.10, the suspend function stopped working.
Upon looking at the /var/log/syslog, this is what I found:
libupower-glib-CRITICAL: up_client_get_can_suspend: assertion `UP_IS_CLIENT (client)'
failed
And it looks like there's a bug filed for it:
https://bugs.launchpad.net/ubuntu/+source/gnome-session/+bug/1066057
I guess the guys are still trying to solve it...
Wednesday, 24 October 2012
Knockoutjs - using the same variable with the 'with' binding and nested 'text' binding
I'm working on a demo for a meetup presentation next week, and initially I had something like this:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/knockout-2.1.0.js"></script>
</head>
<body>
<p>Choose your costume:
<select data-bind="options: availableCostumes, optionsCaption: 'Choose one...', value: selectedCostume"></select>
</p>
<div data-bind="with: selectedCostume">
On Halloween this year, I will be a <span data-bind="text: makeScaryCostume"></span>.
</div>
</body>
<script type="text/javascript">
function CostumeViewModel() {
var self = this;
self.selectedCostume = ko.observable(null);
self.availableCostumes = ko.observableArray(['Pirate', 'Ghost', 'Banana']);
self.makeScaryCostume = ko.computed(function() {
return "very scary " + self.selectedCostume();
}, self);
};
ko.applyBindings(new CostumeViewModel());
</script>
</html>
However, whenever I run this, the following error message happens:
Uncaught Error: Unable to parse bindings.
Message: ReferenceError: makeScaryCostume is not defined;
Bindings value: text: makeScaryCostume knockout-2.1.0.js:48
a.a.extend.parseBindingsString knockout-2.1.0.js:48
a.a.extend.getBindings knockout-2.1.0.js:48
a.h.disposeWhenNodeIsRemoved
The problem is that the 'with' binding creates a context for the nested elements, so within that inner div, it doesn't have access to the view model. The solution is to use the built-in $root reference, which refers to the view model. From there you can use the computed method.
<div data-bind="with: selectedCostume">
On Halloween this year, I will be a <span data-bind="text: $root.makeScaryCostume"></span>.
</div
Sunday, 14 October 2012
Grails UrlMappings.groovy - Mapping a top level controller excludes dbconsole fix
One of the requirements in my app that I'm working on the side involves adding a rewriting rule that maps any top level context to the ProfileController. Initially, it looks like this:
So here is the solution:
class UrlMappings {
static mappings = {
"/${screenName}" (controller: 'profile', action: 'profile')
}
}
So far so good. Unfortunately this poses a problem when I wanted to goto the dbconsole, which is a tool exposed by Grails in development mode to check the contents of the H2 in-mem database. Since everything maps to that controller, even the dbconsole went there.
There is a solution, and that involves the use of the `constraints` param. We simply just have to add a notEqual validator of 'dbconsole' so that it skips the controller mapping. Since the /dbconsole is defined as a servlet-mapping in web.xml, it will filter to that context after Grails decides it cannot handle that uri.
So here is the solution:
class UrlMappings {
static mappings = {
"/${screenName}" {
controller = 'profile'
action = 'profile'
constraints { screenName(notEqual: 'dbconsole') }}
}
}
Friday, 12 October 2012
HTML element: be careful of using element.value where there are newlines!
I'm working on a project where it uses a dirty check mechanism to warn the users on the page to save their data, and it uses element.value to retrieve the value for all form fields, and compare against the values at the time that the user navigates away from the page. This works great but unfortunately I found that element.value and $(element).val() does not always equal each other.
You see, in OS specific systems, if there is a new line character, it will interpret it as \r\n, where as other OSes will interpret it as \n. By wrapping the element in jQuery, it will `normalize` the data for you so you don't have to worry about the subtle differences. For us it was essential that they have to be consistent, which is why one should use the jQuery implementation of .val() instead of element.value.
Monday, 8 October 2012
Grails exception after changing UrlMappings.groovy
I got this strange exception after changing the UrlMappings.groovy in one of my Grails applications today:
plugins.AbstractGrailsPluginManager Plugin [controllers:2.1.0] could not reload changes to file [/home/tchan/repo/privategram/grails-app/controllers/com/privategram/DashboardController.groovy]: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass
java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.reflect.InvocationTargetException
... 1 more
Caused by: java.lang.NullPointerException
... 1 more
[/privategram].[default] Servlet.service() for servlet [default] in context with path [/privategram] threw exception
java.lang.RuntimeException: java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass
at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.checkDevelopmentReloadingState(UrlMappingsFilter.java:298)
at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:199)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:200)
at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:151)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at javax.servlet.FilterChain$doFilter.call(Unknown Source)
at org.grails.plugin.resource.DevModeSanityFilter.doFilter(DevModeSanityFilter.groovy:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:40)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.codehaus.groovy.grails.plugins.springsecurity.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:69)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.RuntimeException: Unable to locate constructor with Class parameter for class org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass
... 1 more
Caused by: java.lang.reflect.InvocationTargetException
... 1 more
Caused by: java.lang.NullPointerException
... 1 more
I doubled checked my UrlMappings again and they seemed fine, so I was pretty certain it was something to do with the reloading, and sure enough, after restarting the app, everything was okay. I guess they didn't tell you that not everything is reloadable?Saturday, 22 September 2012
Troubleshooting performance problems Apache HTTPD with PHP
I was tasked with troubleshooting some of the performance issues we were encountering for one of my projects. In a nutshell, the project is taking an board exam from a desktop-based solution to a web-based one. The test scenario was constructed using Apache JMeter, and it simulated 120 concurrent students taking the exams at the same time. While there were nothing wrong with the average response times, we were able to consistently reproduce a max response time of over 80 seconds, which is very high. It was suspicious to me because even querying the static resources took that long for the max response, which indicated to me that this might not be because of a code issue. After a couple of weeks of investigation, I looked at the logs and found this:
[Sat Sep 15 14:46:57 2012] [warn] Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting.
Right there that indicated to me that perhaps we were not allocating enough threads, and my suspicions were right....so I looked at the config under %httpd_home%/conf/extras/httpd-mpm.conf, but I could find any problems with the settings. Turns out, by default it actually disabled the inclusion of that config file in httpd.conf.
I just uncommented it out and restarted.
I then ran the test again, and voila the max time decreased dramatically to 7 seconds) which is acceptable by the client.
[Sat Sep 15 14:46:57 2012] [warn] Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting.
Right there that indicated to me that perhaps we were not allocating enough threads, and my suspicions were right....so I looked at the config under %httpd_home%/conf/extras/httpd-mpm.conf, but I could find any problems with the settings. Turns out, by default it actually disabled the inclusion of that config file in httpd.conf.
I just uncommented it out and restarted.
I then ran the test again, and voila the max time decreased dramatically to 7 seconds) which is acceptable by the client.
Subscribe to:
Posts (Atom)