셀레니움을 통한 웹 테스트 준비 스크립트


드라이버 가져오기

ChromeDriver

get_chromedriver.sh
#!/bin/bash
os_name=`uname`
chromedriver_dir="chromedriver"
if [ ! -d $chromedriver_dir ]; then
mkdir $chromedriver_dir
fi

echo "downloading chromedriver"

if [[ $os_name == 'Linux' && ! -f $chromedriver_dir/chromedriver ]]; then
cd chromedriver && curl -L https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip > tmp.zip && unzip -o tmp.zip && rm tmp.zip
# wait until download finish
sleep 5
elif [[ $os_name == 'Darwin' && ! -f $chromedriver_dir/chromedriver ]]; then
cd chromedriver && curl -L https://chromedriver.storage.googleapis.com/2.29/chromedriver_mac64.zip | tar xz
sleep 5
fi

GeckoDriver

get_geckdriver.sh
#!/bin/bash
os_name=`uname`

if [ -f geckodriver ]; then
exit 0
fi
echo "downloading gechdriver"

if [[ $os_name == 'Linux' ]]; then
cd ../ && curl -L https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz | tar xz
sleep 5
elif [[ $os_name == 'Darwin' ]]; then
cd ../ && curl -L https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-macos.tar.gz | tar xz
sleep 5
fi

Selenium

Selenium 가져오기

get_selenium.sh
#!/bin/bash

#check if selenium server is up running
pid=`lsof -ti tcp:4444`
if [ $? -eq 0 ]
then
kill -9 $pid
fi
java -jar -Dwebdriver.gecko.driver=../geckodriver -Dwebdriver.chrome.driver="chromedriver/chromedriver" ../webdriverio-test/selenium-server-standalone-3.0.1.jar &

환경설정

Linux

setup_linux_env.sh
#!/bin/bash

if [ "${TRAVIS_OS_NAME}" == "linux" ]
then
export CHROME_BIN="/usr/bin/google-chrome"
export DISPLAY=:99.0
sh -e /etc/init.d/xvfb start &
fi

OSX

setup_osx_env.sh
#!/bin/bash
if [ "${TRAVIS_OS_NAME}" == "osx" ]
then
brew cask install google-chrome
sudo Xvfb :99 -ac -screen 0 1024x768x8 &
export CHROME_BIN="/Applications/Google Chrome.app"
fi

테스트환경 검사

test_setup.sh
#!/bin/bash

EXIT_STATUS=0

function check_command {
"$@"
local STATUS=$?
if [ $STATUS -ne 0 ]; then
echo "error with $1 ($STATUS)" >&2
EXIT_STATUS=$STATUS
fi
}

check_command tests/scripts/get_geckdriver.sh
sleep 5
check_command tests/scripts/get_selenium.sh
sleep 5
check_command tests/scripts/get_chromedriver.sh
sleep 10
check_command tests/scripts/selenium_connect.sh
sleep 10

exit $EXIT_STATUS


블로그 이미지

B급 감성

,


Javascript XPath를 이용해서 Dom Element 가져오기


function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

console.log( getElementByXpath("//html[1]/body[1]/div[1]") );


블로그 이미지

B급 감성

,

Spring-boot RestAPI 와 Spring Security OAuth2 연동(spring-boot 1.5.10 기준)

Dependency 추가

Gradle

dependencies {
...
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.security.oauth:spring-security-oauth2')
...
}

Maven

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>

인증URL 설정

ResourceServerConfig.java

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

@Override
public void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable().and()
.authorizeRequests()
.antMatchers("/swagger-resources/**","/swagger-ui.html",
"/v2/api-docs", "/webjars/**").permitAll() // Swagger Support
.antMatchers("/", "/api/public-key", "/error").permitAll()
.anyRequest().authenticated()
;
}
}
@EnableResourceServer 어노테이션을 추가한 클래스가 만들어지면 기본적으로 모든요청에 대해 인증을 필요로하게 된다.
특정 url에 대해서 인증을 필요로하지 않을 경우 위와같이하면 permitAll 을 제외한 모든 요청에 인증이 필요하다는 설정이고
또는 특정 url에 대해서만 인증이 필요하다면 permitAll과 authenticated 호출하는 부분의 순서를 바꿔주면 된다.

properties 추가

application.yml

security.oauth2:
client.client-id: foo
client.client-secret: bar
resource.token-info-uri: http://192.168.88.133:8780/oauth/check_token
auth-server-uri: http://192.168.88.133:8780
token요청 및 검증을 위해 인증서버의 tokin-info-uri와 client id/secret 등 설정이 추가되어야함

Swagger 관련 설정

SwaggerConfig.java

@Value("${security.oauth2.auth-server-uri}")
private String authServer;
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String clientSecret;


@Bean
public Docket api(ServletContext servletContext) {
return new Docket(DocumentationType.SWAGGER_2)
....
.securitySchemes(Arrays.asList(securityScheme()))
.securityContexts(securityContexts())
....
;
}

@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.scopeSeparator(",")
.useBasicAuthenticationWithAccessCodeGrant(true)
.build();
}

private SecurityScheme securityScheme() {
GrantType grantType = new AuthorizationCodeGrantBuilder()
.tokenEndpoint(new TokenEndpoint(authServer + "/oauth/token", "oauthtoken"))
.tokenRequestEndpoint(
new TokenRequestEndpoint(authServer + "/oauth/authorize", clientId, clientSecret))
.build();
SecurityScheme oauth = new OAuthBuilder().name("spring_oauth")
.grantTypes(Arrays.asList(grantType))
.scopes(Arrays.asList(scopes()))
.build();
return oauth;
}
private AuthorizationScope[] scopes() {
AuthorizationScope[] scopes = {
new AuthorizationScope("read", "for read operations"),
new AuthorizationScope("write", "for write operations")
};
return scopes;
}

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContexts = new ArrayList<>();
        String paths[] = {
                "/api/dashboard.*",
                "/api/metric-statistics.*"
        };

        for (String path: paths) {
            securityContexts.add(SecurityContext.builder()
                    .securityReferences(Arrays.asList(new SecurityReference("spring_oauth", scopes())))
                    .forPaths(PathSelectors.regex(path))
                    .build());
        }

        return securityContexts;
    }
Oauth서버의 해당클라이언트에 허용가능한 scope와 인증이 필요한 API Path등을 Swagger에 적용한다


블로그 이미지

B급 감성

,