Feng erdong's Blog

Life is beautiful

Fix the “Failure Initializing Default System SSL Context” Issue

| Comments

Encountered this problem when I try to resolve dependencies for a gradle project, the root cause is a ssl certificate file can not be found in JDK installation.

Find below solution on internet:

1
2
3
4
5
6
7
8
9
#!/bin/sh
set -e
#the location of certificate file which gradle asks for, create the directory if it's not existed.
cacerts=/Library/Java/JavaVirtualMachines/1.6.0_38-b04-436.jdk/Contents/Home/lib/security/cacerts

curl 'https://docs.codehaus.org/download/attachments/158859410/startssl-CA.pem?version=1&modificationDate=1277952972158' \
      | keytool -import -alias StartSSL-CA -file /dev/stdin -keystore $cacerts -storepass changeit -noprompt
curl 'https://docs.codehaus.org/download/attachments/158859410/startssl-Intermediate.pem?version=1&modificationDate=1277952972182' \
      | keytool -import -alias StartSSL-Intermediate -file /dev/stdin -keystore $cacerts -storepass changeit -noprompt

create a new file and paste the code into it, then run with sudoer permission.

Several Ways to Define Ajax Interceptors in AngularJS

| Comments

Original blog: Using Response Interceptors to Show and Hide a Loading Widget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var myApp = angular.module("myApp", []);
myApp.config(['$httpProvider',
    function ($httpProvider) {
        var $http,
            interceptor = ['$q', '$injector',
                function ($q, $injector) {
                    function success(response) {
                        // get $http via $injector because of circular dependency problem
                        $http = $http || $injector.get('$http');
                        if ($http.pendingRequests.length < 1) {
                            console.log('ajax cal respond with success');
                        }
                        return response;
                    }

                    function error(response) {
                        console.log('x', response);
                        // get $http via $injector because of circular dependency problem
                        $http = $http || $injector.get('$http');
                        if ($http.pendingRequests.length < 1) {
                            console.log('ajax call respond with error');
                        }
                        return $q.reject(response);
                    }

                    return function (promise) {
                        console.log('before send ajax request');
                        return promise.then(success, error);
                    };
                }
            ];

        $httpProvider.responseInterceptors.push(interceptor);
    }
]);

Check out the demo

CSS Tricks – Align

| Comments

  • Align text with input radio
1
2
3
4
input[type=radio] {
  vertical-align: middle;
  margin-top: -1px;
}

Run Headless Selenium in Jenkins

| Comments

  • Install vnc4server
1
sudo apt-get install vnc4server
  • Install Xvnc plugin for Jenkins
  • Switch to jenkins user and set password for vnc4server
1
2
3
4
$ su - jenkins
$ vncserver
> Enter a password, and verify it
$ vncserver -kill :1 # or whichever display the vncserver output mentioned
  • Config Jenkins job to run in headless mode by check “Run Xvnc during build”

  • Watch the running job

    • open any VNC client
    • connect to your.server:59xx (xx is the display number output on the Jenkins console for the running job)
    • enter the password you set for vnc4server before

This article is based on From Zero to Headless Browser Tests in Jenkins

Word Process in Linux – GREP

| Comments

  • grep by multi words
1
cat file.txt | grep "word1\|word2\|word3"
  • grep line which doesn’t contains word
1
cat file.txt | grep -v word
  • show n lines above and under greped line
1
cat file.txt | grep -20 word

Testing Using Gradle

| Comments

  • Run a single unit test
1
gradle test -Dtest.single=TestClassName
  • Run test in debug mode
1
gradle test -Dtest.debug

Mockito Advanced Usage

| Comments

  • Return different values at each call
1
2
3
4
when(mockFoo.someMethod())
          .thenReturn(0)
          .thenReturn(1)
          .thenReturn(-1);
  • Inject dependency in Mockito
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class InjectMocksTest {

  @Mock
  private EJBBeanInjectedByContainerInRealCode dependencyBean;
  //Create a mock object with type EJBBeanInjectedByContainerInRealCode and inject it to a spy object.
  //Mockito will try to inject this dependency to target object in this order: Constructor, Property, Field.

  @InjectMocks
  @Spy
  private MyEJBBean ejbBean;
  //Create a spy object of MyEJBBean, all fields annotated with @Mock with injected into this spy object.

  @Before
  public void setUp() {
    initMocks(this);
    //This is required to create all the mock objects and spy objects declared in annotation way.
  }

  @Test
  public void testShouldXXX() throws Exception {

    when(dependencyBean.findSomeDataFromDB(anyString(), anyString(), anyString())).thenReturn(anyList());
    //Mock the behavior the the injected dependency.

    Object[] objects = ejbBean.myMethod();
    //Call the real method on the spy object.

    assertThat(objects).isNotEmpty();
  }
}

Verify method call

  • Verify method called with expected arguments
1
2
3
4
5
6
7
8
9
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(errors, atLeastOnce()).add(argument.capture(), any(ActionMessage.class));
//Verify errors.add(_, _) called with expected arguements, mockito will store captured arguemnt into the ArgumentCaptor object.

List<String> values = argument.getAllValues();
//If method called only once, use getValue() to get the value passed in, if caleed multi times, use getAllVales() to get value list.

assertTrue(values.contains("exception.message"));
assertTrue(values.contains("exception.detail"));
  • Verify method never called
1
verify(someObject, never()).someMethod(anyString(), anyString());

FAQ of Selenium

| Comments

  • How to simulate press ENTER key
1
2
3
4
@And("^i press enter key$")
public void i_press_enter_key() throws Throwable {
  driver.findElement(By.id("gbqfq")).sendKeys(Keys.ENTER);
}
  • How can wait until a element display or clickable.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Then("^i should see at least (\\d+) results related to my search keyword$")
public void i_should_see_at_least_results_related_to_my_search_keyword(int amount) throws Throwable {
  WebDriverWait wait = new WebDriverWait(driver, 10);
  wait.until(ExpectedConditions.elementToBeClickable(By.id("pnnext")));

  List<WebElement> results = driver.findElements(By.cssSelector("li.g"));

  assertThat(results.size()).isGreaterThan(amount);

  List<String> resultTexts = Lambda.extract(results, on(WebElement.class).getText());
  for (String text : resultTexts) {
    assertThat(text).containsIgnoringCase(keyword);
  }
}

Cucumber JVM

| Comments

Cucumber-JVM command line interface

Usage: java cucumber.api.cli.Main [options] [ [FILE|DIR][:LINE[:LINE]*] ]+

Options:

  • -g, –glue PATH Where glue code (step definitions and hooks) is loaded from.
  • -f, –format FORMAT[:PATH_OR_URL] How to format results. Goes to STDOUT unless PATH_OR_URL is specified. Available formats: junit, html, pretty, progress, json, json-pretty.
  • -t, –tags TAG_EXPRESSION Only run scenarios tagged with tags matching TAG_EXPRESSION.
  • -n, –name REGEXP Only run scenarios whose names match REGEXP.
  • -d, –[no-]-dry-run Skip execution of glue code.
  • -m, –[no-]-monochrome Don’t colour terminal output.
  • -s, –[no-]-strict Treat undefined and pending steps as errors.
  • --dotcucumber PATH_OR_URL Where to write out runtime information. PATH_OR_URL can be a file system path or a URL.
  • -v, –version Print version.
  • -h, –help You’re looking at it.

IDE support

Be able to run *.feature files directly without any configuration in IntelliJ, you should put feature files as the same package structure as glue code.

Like:

–src –test

--java
  --com
    --cukes
      --XXXStepdefs.java
      --YYYStepdefs.java
--resources
  --com
    --cukes
      --features
        --XXX.feature
        --YYY.feature

Useful Gradle Configuration

| Comments

Basic configuration

  • Must have: java plugin, maven repo, dependencies
1
2
3
4
5
6
7
8
9
10
11
12
13
apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
  testCompile 'info.cukes:cucumber-java:1.1.3'\
    , 'info.cukes:cucumber-junit:1.1.3'\
    , 'junit:junit:4.11'\
    , 'org.seleniumhq.selenium:selenium-java:2.32.0'\
    , 'org.easytesting:fest-assert:1.4'
}
  • Enable to run cucumber (with selenium)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
configurations {
  cucumberRuntime {
    extendsFrom testRuntime
  }
}

task cucumber() {
  dependsOn assemble, compileTestJava
    doLast {
      javaexec {
        main = "cucumber.api.cli.Main"
          jvmArgs = ["-Dwebdriver.chrome.driver=/Users/edfeng/Downloads/chromedriver"]
          //Must set if you want to use chrome webdriver
          classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
          args = ["-g", "gradle.cucumber", "src/test/resources"]
          // 1. must set package name of glue code(where steps are defined). 2. must set directory of feature files.
      }
    }
}

Advanced configuration

  • Create gradle based project from template

Simply add the following to your ~/.gradle/init.gradle script:

1
2
3
  gradle.beforeProject { prj ->
    prj.apply from: 'http://www.tellurianring.com/projects/gradle-plugins/gradle-templates/apply.groovy'
  }

Type gradle tasks in any place where you want to create a gradle project, choose one from Template Tasks.

  • Show dependencies gradle dependencies
  • Specify source and test folders.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sourceSets {
  main {
    java {
      srcDir 'mysubfolder/src/main/java'
    }
    resources {
      srcDir 'mysubfolder/src/main/resources'
    }
  }
  test {
    java {
      srcDir 'mysubfolder/src/test/java'
    }
    resources {
      srcDir 'mysubfolder/src/test/resources'
    }
  }
}
  • Configue dependencies using local jar files
1
2
3
4
dependencies {
  compile fileTree (dir: 'file:/home/edfeng/somedir', includes: ['*.jar'])
  testCompile fileTree (dir: 'file:../../somedir', includes: ['ViewController.jar'])
}
  • Show all rumtime dependencies(This can also print out local libaries)
1
2
3
task printAllDependencies() {
      configurations.runtime.each { File f -> println f }
}