SlideShare a Scribd company logo
PhantomJS 
Автоматизация WebKit на JavaScript
fun-box.ru/ulsk 
Илья Василевский 
Разработчик на Ruby и CoffeeScript 
github.com/vassilevsky
1995 — 2014 (19 лет) 
Trolltech → Nokia → Digia 
C++ 
Android, Embedded Linux, iOS, OS X, QNX / 
BlackBerry 10, Sailfish OS, VxWorks, 
Wayland, Windows, Windows CE, X11 
(GNU/Linux, FreeBSD, HP-UX, Solaris, AIX) 
http://qt-project.org
Qt Core 
Qt GUI 
Qt Widgets 
Qt QML and JavaScript 
Qt Quick 
Qt Quick Controls 
Qt Quick Layouts 
Qt Network 
Qt Multimedia 
Qt Multimedia Widgets 
Qt SQL 
Qt WebKit 
Qt WebKit Widgets 
Qt Test
#include <QApplication> 
#include <QMenu> 
#include <QPixmap> 
#include <QWidget> 
#include <qmacfunctions.h> 
int main(int argc, char **argv) 
{ 
QApplication app(argc, argv); 
QWidget widget; 
widget.show(); 
// Pixmap <-> CGImage conversion 
QPixmap pixmap(":qtlogo.png"); 
CGImageRef cgImage = QtMac::toCGImageRef(pixmap); 
QPixmap pixmap2 = QtMac::fromCGImageRef(cgImage); 
return app.exec(); 
}
require 'Qt' 
require './qrc_systray.rb' 
require './window.rb' 
app = Qt::Application.new(ARGV) 
if !Qt::SystemTrayIcon.isSystemTrayAvailable 
Qt::MessageBox.critical( 
nil, 
Qt::Object.tr("Systray"), 
Qt::Object.tr("I couldn't detect any system tray on this system.") 
) 
exit 1 
end 
window = Window.new 
window.show 
app.exec
Qt Core 
Qt GUI 
Qt Widgets 
Qt QML and JavaScript 
Qt Quick 
Qt Quick Controls 
Qt Quick Layouts 
Qt Network 
Qt Multimedia 
Qt Multimedia Widgets 
Qt SQL 
Qt WebKit 
Qt WebKit Widgets 
Qt Test
QWindow 
QWebView 
QWidget QWebPage 
QWidget 
QWebFrame
Ariya Hidayat 
VP of Engineering at @ShapeSecurity 
Doctorate degree (with great honor) in Electrical Engineering 
from University of Paderborn (Germany) 
Master degree from Institute of Technology Bandung (Indonesia) 
with an exchange program with Technical University Munich (Germany) 
Bachelor degree (with honor) from Institute of Technology Bandung (Indonesia) 
Indonesian, English, German 
Indonesia → Mountain View, California 
@AriyaHidayat
Qt WebKit 
JavaScript 
API Engine 
Web 
Server 
Mongoose 
Ghost Driver 
Remote 
Selenium WebDriver 
(Wire Protocol) 
JavaScript 
Engine
$ ls -l phantomjs-1.9.7-linux-x86_64/bin 
total 74896 
-rwxr-xr-x@ 1 vassilevsky staff 38346752 26 янв 2014 phantomjs 
X11 (v1.5+) 
freetype 
fontconfig
// goodbye_world.js 
console.log('Goodbye, cruel world!'); 
phantom.exit(); 
$ phantomjs goodbye_world.js 
Goodbye, cruel world!
// screenshot.js 
var page = require('webpage').create(); 
page.open('http://www.therestartpage.com', function(status) { 
if (status == 'success') { 
page.render('restart.png'); 
} 
phantom.exit(); 
}); 
$ phantomjs screenshot.js 
$ open restart.png
// stealing.js 
var page = require('webpage').create(); 
page.open('http://victim.com', function(status) { 
if (status == 'success') { 
var usefulValue = page.evaluate(function() { 
return document.getElementById('secretId').textContent; // runs on page 
}); 
console.log('Stolen: ' + usefulValue); 
} 
phantom.exit(); 
}); 
$ phantomjs stealing.js 
Stolen: uid123456789
Qt WebKit 
JavaScript API Engine 
JavaScript Engine 
function() { 
return document.getElementById('secretId').textContent; 
} 
var page = require('webpage').create(); 
page.open('http://victim.com', function(status) { 
if (status == 'success') { 
var usefulValue = page.evaluate( ); 
console.log('Stolen: ' + usefulValue); 
} 
phantom.exit(); 
}); 
Qt WebKit
var page = require('webpage').create(); 
doSomeWork = function(param1, param2, param3) { 
doSomethingWith(param1); // runs on page 
useSomehow(param2); // runs on page 
disregard(param3); // runs on page 
} 
page.open('http://example.com', function() { 
page.evaluate(doSomeWork, value1, value2, value3); 
phantom.exit(); 
});
var page = require('webpage').create(); 
Qt WebKit 
JavaScript API Engine 
page.open('http://example.com', function() { 
page.evaluate(doSomeWork, value1, value2, value3); 
phantom.exit(); 
}); 
JavaScript Engine 
function(param1, param2, param3) { 
doSomethingWith(param1); 
useSomehow(param2); 
disregard(param3); 
} 
Qt WebKit
var page = require('webpage').create(); 
Qt WebKit 
JavaScript API Engine 
page.open('http://example.com', function() { 
page.evaluate(doSomeWork, value1, value2, value3); 
phantom.exit(); 
}); 
JavaScript Engine 
function(param1, param2, param3) { 
doSomethingWith(param1); 
useSomehow(param2); 
disregard(param3); 
} 
Qt WebKit 
J S O N
PROPERTIES 
canGoBack 
canGoForward 
clipRect 
content 
cookies 
customHeaders 
event 
focusedFrameName 
frameContent 
frameName 
framePlainText 
frameTitle 
frameUrl 
framesCount 
framesName 
libraryPath 
navigationLocked 
offlineStoragePath 
offlineStorageQuota 
ownsPages 
pages 
pagesWindowName 
paperSize 
plainText 
scrollPosition 
settings 
title 
url 
viewportSize 
windowName 
zoomFactor 
METHODS 
addCookie 
childFramesCount 
childFramesName 
clearCookies 
close 
currentFrameName 
deleteCookie 
evaluate 
evaluateAsync 
evaluateJavaScript 
getPage 
go 
goBack 
goForward 
includeJs 
injectJs 
open 
openUrl 
release 
reload 
render 
renderBase64 
sendEvent 
setContent 
stop 
switchToChildFrame 
switchToFocusedFrame 
switchToFrame 
switchToMainFrame 
switchToParentFrame 
uploadFile 
HANDLERS 
onAlert 
onCallback 
onClosing 
onConfirm 
onConsoleMessage 
onError 
onFilePicker 
onInitialized 
onLoadFinished 
onLoadStarted 
onNavigationRequested 
onPageCreated 
onPrompt 
onResourceError 
onResourceReceived 
onResourceRequested 
onResourceTimeout 
onUrlChanged
require 'childprocess' 
def phantomjs(script, timeout) 
output, input = IO.pipe 
phantomjs = ChildProcess.new("/usr/local/bin/phantomjs", "--disk-cache=true", script) 
phantomjs.io.stdout = input 
phantomjs.io.stderr = input 
Timeout.timeout(timeout) do 
phantomjs.start 
input.close 
logger.info("Attaching to PhantomJS's STDOUT and STDERR...") 
output.each_line{|line| logger.info("[PhantomJS] #{line}") } 
end 
rescue Timeout::Error 
logger.warn("PhantomJS is running longer than expected. Shutting it down...") 
phantomjs.stop 
end
page = require('webpage').create() 
page.viewportSize = {width, height} 
prepareTrack = (i) -> 
track = tracks[i] 
page.evaluate(drawTrack, track.bounds, track.locations) 
setTimeout(renderTrack, MAP_LOADING_TIME, i) 
renderTrack = (i) -> 
track = tracks[i] 
page.render(track.imagePath) 
if i + 1 == tracks.length 
phantom.exit() 
else 
prepareTrack(i + 1) 
drawTrack = (bounds, locations) -> 
setBounds(bounds) 
drawTrackLine(locations) 
page.open(hostPage) 
setTimeout(renderTrack, MAP_LOADING_TIME, 0)
!!! 5 
%html 
%head 
%meta{charset: "utf-8"} 
:css 
#map_container { position: absolute; left: 0; right: 0; top: 0; bottom: 0 } 
%body 
#map_container 
%script{src: "http://api-maps.yandex.ru/2.1/?lang=ru_RU"} 
:coffeescript 
@map = null 
ymaps.ready => 
@map = new ymaps.Map 'map_container' 
@setBounds = (bounds) -> 
@map.setBounds(bounds) 
@drawTrackLine = (locations) -> 
points = (location.point for location in locations) 
@map.geoObjects.add(new ymaps.Polyline(points))
RSpec Cucumber MiniTest 
Capybara 
Poltergeist 
PhantomJS
require 'capybara/poltergeist' 
Capybara.javascript_driver = :poltergeist 
Capybara.methods += 
page.evaluate_script 
page.execute_script 
page.within_frame 
page.within_window 
page.status_code 
page.response_headers 
page.save_screenshot 
page.driver.render_base64(format, options) 
page.driver.scroll_to(left, top) 
page.driver.basic_authorize(user, password) 
element.native.send_keys(*keys)
JS API 
class Poltergeist.Connection 
constructor: (@owner, @port) -> 
@socket = new WebSocket "ws://127.0.0.1:#{@port}/" 
@socket.onmessage = this.commandReceived 
@socket.onclose = -> phantom.exit() 
WebKit 
module Capybara::Poltergeist 
class Server 
attr_reader :socket, :fixed_port, :timeout 
def start 
@socket = WebSocketServer.new(fixed_port, timeout) 
end 
def send(message) 
@socket.send(message) or raise DeadClient.new(message) 
end 
end 
end
class Poltergeist.WebPage 
onErrorNative: (message, stack) -> 
stackString = message 
stack.forEach (frame) -> 
stackString += "n" 
stackString += " at #{frame.file}:#{frame.line}" 
stackString += " in #{frame.function}" if frame.function && frame.function != '' 
@errors.push(message: message, stack: stackString) 
class Poltergeist.Browser 
sendResponse: (response) -> 
errors = @currentPage.errors 
@currentPage.clearErrors() 
if errors.length > 0 && @js_errors 
@owner.sendError(new Poltergeist.JavascriptError(errors)) 
else 
@owner.sendResponse(response)
Casper.js 
Chutzpah 
Ghostbuster 
GhostDriver 
Lotte 
Poltergeist 
Capybara 
pjscrape 
WebSpecter 
conjure 
PhantomJS Google Charts 
capturejs 
pageres 
phantomjs-screenshots 
screenshot-app 
screenshot-as-a-service 
screenshot-service 
screenshot 
screenshot-webservice 
pyshotx 
node-webshot 
pageres 
django-screamshot 
PHP Screen 
grabshot 
basset 
Compass Magick 
Confess 
GhostStory 
Grover 
Grunt 
Guard PhantomJS 
phridge 
phantomjs-node 
node-phantom 
phantom-proxy 
phantomas 
PhantomCSS 
PhantomFlow 
phantomjs-maven-plugin 
grunt-lib-phantomjs 
grunt-contrib-qunit 
PhantomLint 
PhantomXHR 
shortcut.io 
Slippy 
SpookyJS 
Yeoman
За внимание спасибо

More Related Content

What's hot

Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
Nelson Glauber Leal
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
Domenic Denicola
 
Firefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobileFirefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobileRobert Nyman
 
The jsdom
The jsdomThe jsdom
The jsdom
Domenic Denicola
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
Seonki Paik
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
Nelson Glauber Leal
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
Laurent_VB
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
장현 한
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
GITS Indonesia
 
Jeroen Vloothuis Bend Kss To Your Will
Jeroen Vloothuis   Bend Kss To Your WillJeroen Vloothuis   Bend Kss To Your Will
Jeroen Vloothuis Bend Kss To Your Will
Vincenzo Barone
 
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScriptThe Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
Hazelcast
 
State management in a GraphQL era
State management in a GraphQL eraState management in a GraphQL era
State management in a GraphQL era
kristijanmkd
 
Cooking Up Drama - ChefConf 2015
Cooking Up Drama - ChefConf 2015 Cooking Up Drama - ChefConf 2015
Cooking Up Drama - ChefConf 2015
Chef
 
Cooking Up Drama
Cooking Up DramaCooking Up Drama
Cooking Up Drama
bridgetkromhout
 
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Techsylvania
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
名辰 洪
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype APIRyo Jin
 
Node.js for enterprise - JS Conference
Node.js for enterprise - JS ConferenceNode.js for enterprise - JS Conference
Node.js for enterprise - JS Conference
Timur Shemsedinov
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
Jared Erickson
 

What's hot (20)

Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
 
Firefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobileFirefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobile
 
The jsdom
The jsdomThe jsdom
The jsdom
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
 
Jeroen Vloothuis Bend Kss To Your Will
Jeroen Vloothuis   Bend Kss To Your WillJeroen Vloothuis   Bend Kss To Your Will
Jeroen Vloothuis Bend Kss To Your Will
 
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScriptThe Power of the JVM: Applied Polyglot Projects with Java and JavaScript
The Power of the JVM: Applied Polyglot Projects with Java and JavaScript
 
State management in a GraphQL era
State management in a GraphQL eraState management in a GraphQL era
State management in a GraphQL era
 
Cooking Up Drama - ChefConf 2015
Cooking Up Drama - ChefConf 2015 Cooking Up Drama - ChefConf 2015
Cooking Up Drama - ChefConf 2015
 
Cooking Up Drama
Cooking Up DramaCooking Up Drama
Cooking Up Drama
 
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and R...
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype API
 
Node.js for enterprise - JS Conference
Node.js for enterprise - JS ConferenceNode.js for enterprise - JS Conference
Node.js for enterprise - JS Conference
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
 

Viewers also liked

Js testing
Js testingJs testing
Js testingMaslowB
 
Phantom js quick start
Phantom js quick startPhantom js quick start
Phantom js quick startji guang
 
Introduction to PhantomJS
Introduction to PhantomJSIntroduction to PhantomJS
Introduction to PhantomJS
Erol Selitektay
 
Superfast Automated Web Testing with CasperJS & PhantomJS
Superfast Automated Web Testing with CasperJS & PhantomJS Superfast Automated Web Testing with CasperJS & PhantomJS
Superfast Automated Web Testing with CasperJS & PhantomJS
Hervé Vũ Roussel
 
An introduction to PhantomJS: A headless browser for automation test.
An introduction to PhantomJS: A headless browser for automation test.An introduction to PhantomJS: A headless browser for automation test.
An introduction to PhantomJS: A headless browser for automation test.
BugRaptors
 
Automated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and SeleniumAutomated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and Selenium
Dev9Com
 
The Mobile Story 2016 [Infographic]
The Mobile Story 2016 [Infographic]The Mobile Story 2016 [Infographic]
The Mobile Story 2016 [Infographic]
Ajeet Singh
 

Viewers also liked (7)

Js testing
Js testingJs testing
Js testing
 
Phantom js quick start
Phantom js quick startPhantom js quick start
Phantom js quick start
 
Introduction to PhantomJS
Introduction to PhantomJSIntroduction to PhantomJS
Introduction to PhantomJS
 
Superfast Automated Web Testing with CasperJS & PhantomJS
Superfast Automated Web Testing with CasperJS & PhantomJS Superfast Automated Web Testing with CasperJS & PhantomJS
Superfast Automated Web Testing with CasperJS & PhantomJS
 
An introduction to PhantomJS: A headless browser for automation test.
An introduction to PhantomJS: A headless browser for automation test.An introduction to PhantomJS: A headless browser for automation test.
An introduction to PhantomJS: A headless browser for automation test.
 
Automated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and SeleniumAutomated Testing with Cucumber, PhantomJS and Selenium
Automated Testing with Cucumber, PhantomJS and Selenium
 
The Mobile Story 2016 [Infographic]
The Mobile Story 2016 [Infographic]The Mobile Story 2016 [Infographic]
The Mobile Story 2016 [Infographic]
 

Similar to Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"

Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitAriya Hidayat
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & Webkit
QT-day
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
Ariya Hidayat
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
Ariya Hidayat
 
Analyzing the Performance of Mobile Web
Analyzing the Performance of Mobile WebAnalyzing the Performance of Mobile Web
Analyzing the Performance of Mobile Web
Ariya Hidayat
 
CasperJs Enjoy Functional Testing
CasperJs Enjoy Functional TestingCasperJs Enjoy Functional Testing
CasperJs Enjoy Functional Testing
Fabien POMEROL
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2
Asher Martin
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
Ganesh Gembali
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
Andrew Rota
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
名辰 洪
 
NoSQL and JavaScript: a love story
NoSQL and JavaScript: a love storyNoSQL and JavaScript: a love story
NoSQL and JavaScript: a love story
Alexandre Morgaut
 
OneRing @ OSCamp 2010
OneRing @ OSCamp 2010OneRing @ OSCamp 2010
OneRing @ OSCamp 2010
Qiangning Hong
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
Training: Day Four - Struts, Tiles, Renders and Faces
Training: Day Four - Struts, Tiles, Renders and FacesTraining: Day Four - Struts, Tiles, Renders and Faces
Training: Day Four - Struts, Tiles, Renders and Faces
Artur Ventura
 
FP - Découverte de Play Framework Scala
FP - Découverte de Play Framework ScalaFP - Découverte de Play Framework Scala
FP - Découverte de Play Framework Scala
Kévin Margueritte
 
Drones, Flying robots and Javascript
Drones, Flying robots and JavascriptDrones, Flying robots and Javascript
Drones, Flying robots and Javascript
Laurent Eschenauer
 
Node js introduction
Node js introductionNode js introduction
Node js introductionAlex Su
 

Similar to Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS" (20)

Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKit
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & Webkit
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
 
Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
 
Analyzing the Performance of Mobile Web
Analyzing the Performance of Mobile WebAnalyzing the Performance of Mobile Web
Analyzing the Performance of Mobile Web
 
CasperJs Enjoy Functional Testing
CasperJs Enjoy Functional TestingCasperJs Enjoy Functional Testing
CasperJs Enjoy Functional Testing
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 
NoSQL and JavaScript: a love story
NoSQL and JavaScript: a love storyNoSQL and JavaScript: a love story
NoSQL and JavaScript: a love story
 
OneRing @ OSCamp 2010
OneRing @ OSCamp 2010OneRing @ OSCamp 2010
OneRing @ OSCamp 2010
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Training: Day Four - Struts, Tiles, Renders and Faces
Training: Day Four - Struts, Tiles, Renders and FacesTraining: Day Four - Struts, Tiles, Renders and Faces
Training: Day Four - Struts, Tiles, Renders and Faces
 
FP - Découverte de Play Framework Scala
FP - Découverte de Play Framework ScalaFP - Découverte de Play Framework Scala
FP - Découverte de Play Framework Scala
 
Drones, Flying robots and Javascript
Drones, Flying robots and JavascriptDrones, Flying robots and Javascript
Drones, Flying robots and Javascript
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 

More from Provectus

Сергей Моренец: "Gradle. Write once, build everywhere"
Сергей Моренец: "Gradle. Write once, build everywhere"Сергей Моренец: "Gradle. Write once, build everywhere"
Сергей Моренец: "Gradle. Write once, build everywhere"
Provectus
 
Василий Захарченко: "Взгляд на queryDsl-sql фреймворк как альтернатива Hiber...
Василий Захарченко: "Взгляд на  queryDsl-sql фреймворк как альтернатива Hiber...Василий Захарченко: "Взгляд на  queryDsl-sql фреймворк как альтернатива Hiber...
Василий Захарченко: "Взгляд на queryDsl-sql фреймворк как альтернатива Hiber...
Provectus
 
Get to know provectus
Get to know provectusGet to know provectus
Get to know provectus
Provectus
 
Why I want to Kazan
Why I want to KazanWhy I want to Kazan
Why I want to Kazan
Provectus
 
Артем Тритяк, Lead Front-End developer в Electric Cloud
 Артем Тритяк, Lead Front-End developer в Electric Cloud Артем Тритяк, Lead Front-End developer в Electric Cloud
Артем Тритяк, Lead Front-End developer в Electric Cloud
Provectus
 
Максим Мазурок “Material Design in Web Applications.”
Максим Мазурок “Material Design in Web Applications.”Максим Мазурок “Material Design in Web Applications.”
Максим Мазурок “Material Design in Web Applications.”
Provectus
 
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
Provectus
 
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
Provectus
 
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
Provectus
 
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
Provectus
 
Артем Крикун (AT Production) “Промо-видео для приложений.”
Артем Крикун (AT Production) “Промо-видео для приложений.”Артем Крикун (AT Production) “Промо-видео для приложений.”
Артем Крикун (AT Production) “Промо-видео для приложений.”Provectus
 
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
Provectus
 
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
Provectus
 
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
Provectus
 
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"Provectus
 
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Provectus
 
Логотип — Бизнес или творчество
Логотип — Бизнес или творчествоЛоготип — Бизнес или творчество
Логотип — Бизнес или творчество
Provectus
 
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКАЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
Provectus
 
Требования к заказчику. Роль QA в процессе постановки тех. задания
Требования к заказчику. Роль QA в процессе постановки тех. заданияТребования к заказчику. Роль QA в процессе постановки тех. задания
Требования к заказчику. Роль QA в процессе постановки тех. задания
Provectus
 

More from Provectus (20)

Сергей Моренец: "Gradle. Write once, build everywhere"
Сергей Моренец: "Gradle. Write once, build everywhere"Сергей Моренец: "Gradle. Write once, build everywhere"
Сергей Моренец: "Gradle. Write once, build everywhere"
 
Василий Захарченко: "Взгляд на queryDsl-sql фреймворк как альтернатива Hiber...
Василий Захарченко: "Взгляд на  queryDsl-sql фреймворк как альтернатива Hiber...Василий Захарченко: "Взгляд на  queryDsl-sql фреймворк как альтернатива Hiber...
Василий Захарченко: "Взгляд на queryDsl-sql фреймворк как альтернатива Hiber...
 
Get to know provectus
Get to know provectusGet to know provectus
Get to know provectus
 
Why I want to Kazan
Why I want to KazanWhy I want to Kazan
Why I want to Kazan
 
Артем Тритяк, Lead Front-End developer в Electric Cloud
 Артем Тритяк, Lead Front-End developer в Electric Cloud Артем Тритяк, Lead Front-End developer в Electric Cloud
Артем Тритяк, Lead Front-End developer в Electric Cloud
 
Hackathon
HackathonHackathon
Hackathon
 
Максим Мазурок “Material Design in Web Applications.”
Максим Мазурок “Material Design in Web Applications.”Максим Мазурок “Material Design in Web Applications.”
Максим Мазурок “Material Design in Web Applications.”
 
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
Дима Гадомский (Юскутум) “Можно ли позаимствовать дизайн и функционал так, чт...
 
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
Михаил Лебединский (Termopal) “Особенности разработки веб и мобильных приложе...
 
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
Федор Поляков (Looksery) “Face Tracking на мобильных устройствах в режиме реа...
 
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
Виталий Чмыхун (Provectus) “Как мы автоматизировали мобайл деплоймент.”
 
Артем Крикун (AT Production) “Промо-видео для приложений.”
Артем Крикун (AT Production) “Промо-видео для приложений.”Артем Крикун (AT Production) “Промо-видео для приложений.”
Артем Крикун (AT Production) “Промо-видео для приложений.”
 
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
Роман Колос (ComboApp) “Методология использования инструментов аналитики в ма...
 
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
Галина Дивакова (Clickky) “Вывод мобильных приложений в ТОП.”
 
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
Евгений Плохой (CapableBits) “Продвижение приложений до и после выхода на рын...
 
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"
Сергей Укустов (Provectus IT): "Несоциалочка на Рельсах"
 
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
 
Логотип — Бизнес или творчество
Логотип — Бизнес или творчествоЛоготип — Бизнес или творчество
Логотип — Бизнес или творчество
 
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКАЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
ЕСЛИ БЫ УОЛТ ДИСНЕЙ ДЕЛАЛ ИНТЕРФЕЙСЫ. MOTION DESIGN. ПРАКТИКА
 
Требования к заказчику. Роль QA в процессе постановки тех. задания
Требования к заказчику. Роль QA в процессе постановки тех. заданияТребования к заказчику. Роль QA в процессе постановки тех. задания
Требования к заказчику. Роль QA в процессе постановки тех. задания
 

Recently uploaded

Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Game Development with Unity3D (Game Development lecture 3)
Game Development  with Unity3D (Game Development lecture 3)Game Development  with Unity3D (Game Development lecture 3)
Game Development with Unity3D (Game Development lecture 3)
abdulrafaychaudhry
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 

Recently uploaded (20)

Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Game Development with Unity3D (Game Development lecture 3)
Game Development  with Unity3D (Game Development lecture 3)Game Development  with Unity3D (Game Development lecture 3)
Game Development with Unity3D (Game Development lecture 3)
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 

Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"

  • 2. fun-box.ru/ulsk Илья Василевский Разработчик на Ruby и CoffeeScript github.com/vassilevsky
  • 3.
  • 4. 1995 — 2014 (19 лет) Trolltech → Nokia → Digia C++ Android, Embedded Linux, iOS, OS X, QNX / BlackBerry 10, Sailfish OS, VxWorks, Wayland, Windows, Windows CE, X11 (GNU/Linux, FreeBSD, HP-UX, Solaris, AIX) http://qt-project.org
  • 5. Qt Core Qt GUI Qt Widgets Qt QML and JavaScript Qt Quick Qt Quick Controls Qt Quick Layouts Qt Network Qt Multimedia Qt Multimedia Widgets Qt SQL Qt WebKit Qt WebKit Widgets Qt Test
  • 6. #include <QApplication> #include <QMenu> #include <QPixmap> #include <QWidget> #include <qmacfunctions.h> int main(int argc, char **argv) { QApplication app(argc, argv); QWidget widget; widget.show(); // Pixmap <-> CGImage conversion QPixmap pixmap(":qtlogo.png"); CGImageRef cgImage = QtMac::toCGImageRef(pixmap); QPixmap pixmap2 = QtMac::fromCGImageRef(cgImage); return app.exec(); }
  • 7. require 'Qt' require './qrc_systray.rb' require './window.rb' app = Qt::Application.new(ARGV) if !Qt::SystemTrayIcon.isSystemTrayAvailable Qt::MessageBox.critical( nil, Qt::Object.tr("Systray"), Qt::Object.tr("I couldn't detect any system tray on this system.") ) exit 1 end window = Window.new window.show app.exec
  • 8.
  • 9. Qt Core Qt GUI Qt Widgets Qt QML and JavaScript Qt Quick Qt Quick Controls Qt Quick Layouts Qt Network Qt Multimedia Qt Multimedia Widgets Qt SQL Qt WebKit Qt WebKit Widgets Qt Test
  • 10. QWindow QWebView QWidget QWebPage QWidget QWebFrame
  • 11. Ariya Hidayat VP of Engineering at @ShapeSecurity Doctorate degree (with great honor) in Electrical Engineering from University of Paderborn (Germany) Master degree from Institute of Technology Bandung (Indonesia) with an exchange program with Technical University Munich (Germany) Bachelor degree (with honor) from Institute of Technology Bandung (Indonesia) Indonesian, English, German Indonesia → Mountain View, California @AriyaHidayat
  • 12. Qt WebKit JavaScript API Engine Web Server Mongoose Ghost Driver Remote Selenium WebDriver (Wire Protocol) JavaScript Engine
  • 13.
  • 14. $ ls -l phantomjs-1.9.7-linux-x86_64/bin total 74896 -rwxr-xr-x@ 1 vassilevsky staff 38346752 26 янв 2014 phantomjs X11 (v1.5+) freetype fontconfig
  • 15. // goodbye_world.js console.log('Goodbye, cruel world!'); phantom.exit(); $ phantomjs goodbye_world.js Goodbye, cruel world!
  • 16. // screenshot.js var page = require('webpage').create(); page.open('http://www.therestartpage.com', function(status) { if (status == 'success') { page.render('restart.png'); } phantom.exit(); }); $ phantomjs screenshot.js $ open restart.png
  • 17. // stealing.js var page = require('webpage').create(); page.open('http://victim.com', function(status) { if (status == 'success') { var usefulValue = page.evaluate(function() { return document.getElementById('secretId').textContent; // runs on page }); console.log('Stolen: ' + usefulValue); } phantom.exit(); }); $ phantomjs stealing.js Stolen: uid123456789
  • 18. Qt WebKit JavaScript API Engine JavaScript Engine function() { return document.getElementById('secretId').textContent; } var page = require('webpage').create(); page.open('http://victim.com', function(status) { if (status == 'success') { var usefulValue = page.evaluate( ); console.log('Stolen: ' + usefulValue); } phantom.exit(); }); Qt WebKit
  • 19. var page = require('webpage').create(); doSomeWork = function(param1, param2, param3) { doSomethingWith(param1); // runs on page useSomehow(param2); // runs on page disregard(param3); // runs on page } page.open('http://example.com', function() { page.evaluate(doSomeWork, value1, value2, value3); phantom.exit(); });
  • 20. var page = require('webpage').create(); Qt WebKit JavaScript API Engine page.open('http://example.com', function() { page.evaluate(doSomeWork, value1, value2, value3); phantom.exit(); }); JavaScript Engine function(param1, param2, param3) { doSomethingWith(param1); useSomehow(param2); disregard(param3); } Qt WebKit
  • 21. var page = require('webpage').create(); Qt WebKit JavaScript API Engine page.open('http://example.com', function() { page.evaluate(doSomeWork, value1, value2, value3); phantom.exit(); }); JavaScript Engine function(param1, param2, param3) { doSomethingWith(param1); useSomehow(param2); disregard(param3); } Qt WebKit J S O N
  • 22. PROPERTIES canGoBack canGoForward clipRect content cookies customHeaders event focusedFrameName frameContent frameName framePlainText frameTitle frameUrl framesCount framesName libraryPath navigationLocked offlineStoragePath offlineStorageQuota ownsPages pages pagesWindowName paperSize plainText scrollPosition settings title url viewportSize windowName zoomFactor METHODS addCookie childFramesCount childFramesName clearCookies close currentFrameName deleteCookie evaluate evaluateAsync evaluateJavaScript getPage go goBack goForward includeJs injectJs open openUrl release reload render renderBase64 sendEvent setContent stop switchToChildFrame switchToFocusedFrame switchToFrame switchToMainFrame switchToParentFrame uploadFile HANDLERS onAlert onCallback onClosing onConfirm onConsoleMessage onError onFilePicker onInitialized onLoadFinished onLoadStarted onNavigationRequested onPageCreated onPrompt onResourceError onResourceReceived onResourceRequested onResourceTimeout onUrlChanged
  • 23. require 'childprocess' def phantomjs(script, timeout) output, input = IO.pipe phantomjs = ChildProcess.new("/usr/local/bin/phantomjs", "--disk-cache=true", script) phantomjs.io.stdout = input phantomjs.io.stderr = input Timeout.timeout(timeout) do phantomjs.start input.close logger.info("Attaching to PhantomJS's STDOUT and STDERR...") output.each_line{|line| logger.info("[PhantomJS] #{line}") } end rescue Timeout::Error logger.warn("PhantomJS is running longer than expected. Shutting it down...") phantomjs.stop end
  • 24. page = require('webpage').create() page.viewportSize = {width, height} prepareTrack = (i) -> track = tracks[i] page.evaluate(drawTrack, track.bounds, track.locations) setTimeout(renderTrack, MAP_LOADING_TIME, i) renderTrack = (i) -> track = tracks[i] page.render(track.imagePath) if i + 1 == tracks.length phantom.exit() else prepareTrack(i + 1) drawTrack = (bounds, locations) -> setBounds(bounds) drawTrackLine(locations) page.open(hostPage) setTimeout(renderTrack, MAP_LOADING_TIME, 0)
  • 25. !!! 5 %html %head %meta{charset: "utf-8"} :css #map_container { position: absolute; left: 0; right: 0; top: 0; bottom: 0 } %body #map_container %script{src: "http://api-maps.yandex.ru/2.1/?lang=ru_RU"} :coffeescript @map = null ymaps.ready => @map = new ymaps.Map 'map_container' @setBounds = (bounds) -> @map.setBounds(bounds) @drawTrackLine = (locations) -> points = (location.point for location in locations) @map.geoObjects.add(new ymaps.Polyline(points))
  • 26. RSpec Cucumber MiniTest Capybara Poltergeist PhantomJS
  • 27. require 'capybara/poltergeist' Capybara.javascript_driver = :poltergeist Capybara.methods += page.evaluate_script page.execute_script page.within_frame page.within_window page.status_code page.response_headers page.save_screenshot page.driver.render_base64(format, options) page.driver.scroll_to(left, top) page.driver.basic_authorize(user, password) element.native.send_keys(*keys)
  • 28. JS API class Poltergeist.Connection constructor: (@owner, @port) -> @socket = new WebSocket "ws://127.0.0.1:#{@port}/" @socket.onmessage = this.commandReceived @socket.onclose = -> phantom.exit() WebKit module Capybara::Poltergeist class Server attr_reader :socket, :fixed_port, :timeout def start @socket = WebSocketServer.new(fixed_port, timeout) end def send(message) @socket.send(message) or raise DeadClient.new(message) end end end
  • 29. class Poltergeist.WebPage onErrorNative: (message, stack) -> stackString = message stack.forEach (frame) -> stackString += "n" stackString += " at #{frame.file}:#{frame.line}" stackString += " in #{frame.function}" if frame.function && frame.function != '' @errors.push(message: message, stack: stackString) class Poltergeist.Browser sendResponse: (response) -> errors = @currentPage.errors @currentPage.clearErrors() if errors.length > 0 && @js_errors @owner.sendError(new Poltergeist.JavascriptError(errors)) else @owner.sendResponse(response)
  • 30. Casper.js Chutzpah Ghostbuster GhostDriver Lotte Poltergeist Capybara pjscrape WebSpecter conjure PhantomJS Google Charts capturejs pageres phantomjs-screenshots screenshot-app screenshot-as-a-service screenshot-service screenshot screenshot-webservice pyshotx node-webshot pageres django-screamshot PHP Screen grabshot basset Compass Magick Confess GhostStory Grover Grunt Guard PhantomJS phridge phantomjs-node node-phantom phantom-proxy phantomas PhantomCSS PhantomFlow phantomjs-maven-plugin grunt-lib-phantomjs grunt-contrib-qunit PhantomLint PhantomXHR shortcut.io Slippy SpookyJS Yeoman