Representing Material Culture Online: Historic Clothing in OmekaArden Kirkland
In June 2014 I was invited to present at the New York City Digital Humanities (NYCDH) Omeka User’s Group Workshop at the Bard Graduate Center. I spoke about my work with two different collections of historic clothing that are using Omeka as their platform, and shared some of the challenges of representing material culture online. This includes some details of the nuts and bolts behind each project, including samples of customized PHP for showing related items.
This builds on the presentation I gave at the annual symposium for the Costume Society of America, "One of Many Small Collections."
Backdooring the web is the cheapest and most hidden way to achieve
persistence on a compromised network, both if you're looking at
privileges on the webapp itself or at executing command to underlying
system.
During the talk, we will discuss the context of a web backdoor: the
environment where she can born and grow up will be defined.
Each environmental aspect will be thoroughly analyzed: where is the best
point of injection, why we choose a specific function or trick, what
permissions are needed, how to trigger the backdoor in a safe, hidden
and reproducible way, and of course what to inject.
The talk will thus present several ways to inject obfuscated and hard to
spot vulnerabilities in PHP code. Shown examples will backdoor CMS
plugins as well as custom code, altering the code and polluting the
webapp ecosystem (read: DBMS and webservers).
Experiences, Best Pratices How to setup Unit, Functional and Acceptance Tests with PHPUnit and Codeception for TYPO3 Applications. Describes many Codeception modules + Integration with Travis CI
Given it's share of ~80% (W3Techs dixit) with more than 240M active websites (Netcraft dixit) we can say that PHP is the de facto standard for web programming.
We can find she both in made-by-son-of-a-friend-after-dinner websites and on enterprise portals or e-commerce platforms, perhaps because she's available on almost every hosting service and because it's very easy to start with her.
As we should have learnt from history, simplicity hides complexity, therefore a lot of uncommon functions' arguments and little known behaviours.
The talk present ways to insert obfuscated and hard to spot
vulnerabilities in existent code and some naughty functions. For every given example we will show how to trigger the backdoor through the vulnerability and how it works, her pros and cons, and how to detect her.
Representing Material Culture Online: Historic Clothing in OmekaArden Kirkland
In June 2014 I was invited to present at the New York City Digital Humanities (NYCDH) Omeka User’s Group Workshop at the Bard Graduate Center. I spoke about my work with two different collections of historic clothing that are using Omeka as their platform, and shared some of the challenges of representing material culture online. This includes some details of the nuts and bolts behind each project, including samples of customized PHP for showing related items.
This builds on the presentation I gave at the annual symposium for the Costume Society of America, "One of Many Small Collections."
Backdooring the web is the cheapest and most hidden way to achieve
persistence on a compromised network, both if you're looking at
privileges on the webapp itself or at executing command to underlying
system.
During the talk, we will discuss the context of a web backdoor: the
environment where she can born and grow up will be defined.
Each environmental aspect will be thoroughly analyzed: where is the best
point of injection, why we choose a specific function or trick, what
permissions are needed, how to trigger the backdoor in a safe, hidden
and reproducible way, and of course what to inject.
The talk will thus present several ways to inject obfuscated and hard to
spot vulnerabilities in PHP code. Shown examples will backdoor CMS
plugins as well as custom code, altering the code and polluting the
webapp ecosystem (read: DBMS and webservers).
Experiences, Best Pratices How to setup Unit, Functional and Acceptance Tests with PHPUnit and Codeception for TYPO3 Applications. Describes many Codeception modules + Integration with Travis CI
Given it's share of ~80% (W3Techs dixit) with more than 240M active websites (Netcraft dixit) we can say that PHP is the de facto standard for web programming.
We can find she both in made-by-son-of-a-friend-after-dinner websites and on enterprise portals or e-commerce platforms, perhaps because she's available on almost every hosting service and because it's very easy to start with her.
As we should have learnt from history, simplicity hides complexity, therefore a lot of uncommon functions' arguments and little known behaviours.
The talk present ways to insert obfuscated and hard to spot
vulnerabilities in existent code and some naughty functions. For every given example we will show how to trigger the backdoor through the vulnerability and how it works, her pros and cons, and how to detect her.
Code Obfuscation, PHP shells & more
What hackers do once they get passed your code - and how you can detect & fix it.
Content:
- What happens when I get hacked?
- What's code obfuscation?
- What are PHP shells?
- Show me some clever hacks!
- Prevention
- Post-hack cleanup
What is this not about:
- How can I hack a website?
- How can I DoS a website?
- How can I find my insecure code?
Conférence données à l'Open World Forum, 05 octobre 2013.
Comment créer une base de données noSQL par paires clés-valeurs en moins d'une heure, en se basant sur le bibliothèques Nanomsg et LightningDB.
Using Mikko Koppanen's PHP ZMQ extension we will look at how you can easily distribute work to background processes, provide flexible service brokering for your next service oriented architecture, and manage caches efficiently and easily with just PHP and the ZeroMQ libraries. Whether the problem is asynchronous communication, message distribution, process management or just about anything, ZeroMQ can help you build an architecture that is more resilient, more scalable and more flexible, without introducing unnecessary overhead or requiring a heavyweight queue manager node.
One of the most time consuming tasks as a red teamer is diving into filesystems and shares, attempting to identify any potentially sensitive information. Genneraly users store credentials and other sensitive information in local filesystems and this talk has the purpose of explaining how to use the carnivorall as a means to speed up the task of searching important files using several vectors. I will present some proof of concepts, comparisons between tools and my recent success cases in red teaming engagements."
Phing is a PHP build tool, similar to Apache's Ant. Phing can be used for everything from validating your build, running tests, combining/minifying resources to deploying.
I've been building APIs for a long time now and it is becoming ever more common for server-side developer thanks to the rise of front-end JavaScript frameworks, iPhone applications and generally API-centric architectures. On one hand you're just grabbing stuff from a data source and shoving it out as JSON, but surviving changes in business logic, database schema updates, new or deprecated etc gets super difficult.
This talk will outline the common pitfalls developers get trapped in when building APIs and outline methods to avoid them, including naming stuff badly then having to rename everything, when and how to use POST/PUT/PATCH, data structures, DDoSing yourself because pagination, picking your authentication system and all sorts of other stuff.
PyLadies Talk: Learn to love the command line!Blanca Mancilla
This talks aims to uncover some of the magic powers of scripting and the command line.
I'll share with you some of my experience using the shell to schedule backups of a git repository or to find strings in files of unknown name and location.
And then you might see that it is a tough love!
Code Obfuscation, PHP shells & more
What hackers do once they get passed your code - and how you can detect & fix it.
Content:
- What happens when I get hacked?
- What's code obfuscation?
- What are PHP shells?
- Show me some clever hacks!
- Prevention
- Post-hack cleanup
What is this not about:
- How can I hack a website?
- How can I DoS a website?
- How can I find my insecure code?
Conférence données à l'Open World Forum, 05 octobre 2013.
Comment créer une base de données noSQL par paires clés-valeurs en moins d'une heure, en se basant sur le bibliothèques Nanomsg et LightningDB.
Using Mikko Koppanen's PHP ZMQ extension we will look at how you can easily distribute work to background processes, provide flexible service brokering for your next service oriented architecture, and manage caches efficiently and easily with just PHP and the ZeroMQ libraries. Whether the problem is asynchronous communication, message distribution, process management or just about anything, ZeroMQ can help you build an architecture that is more resilient, more scalable and more flexible, without introducing unnecessary overhead or requiring a heavyweight queue manager node.
One of the most time consuming tasks as a red teamer is diving into filesystems and shares, attempting to identify any potentially sensitive information. Genneraly users store credentials and other sensitive information in local filesystems and this talk has the purpose of explaining how to use the carnivorall as a means to speed up the task of searching important files using several vectors. I will present some proof of concepts, comparisons between tools and my recent success cases in red teaming engagements."
Phing is a PHP build tool, similar to Apache's Ant. Phing can be used for everything from validating your build, running tests, combining/minifying resources to deploying.
I've been building APIs for a long time now and it is becoming ever more common for server-side developer thanks to the rise of front-end JavaScript frameworks, iPhone applications and generally API-centric architectures. On one hand you're just grabbing stuff from a data source and shoving it out as JSON, but surviving changes in business logic, database schema updates, new or deprecated etc gets super difficult.
This talk will outline the common pitfalls developers get trapped in when building APIs and outline methods to avoid them, including naming stuff badly then having to rename everything, when and how to use POST/PUT/PATCH, data structures, DDoSing yourself because pagination, picking your authentication system and all sorts of other stuff.
PyLadies Talk: Learn to love the command line!Blanca Mancilla
This talks aims to uncover some of the magic powers of scripting and the command line.
I'll share with you some of my experience using the shell to schedule backups of a git repository or to find strings in files of unknown name and location.
And then you might see that it is a tough love!
Collabnix Community conduct webinar on regular basis. Swapnasagar Pradhan, an engineer from VISA delivered a talk on Traefik this January 11th 2020. Check this out.
Talk tenuto il 13 Dicembre 2016 alla Camera di Commercio di Prato durante il PostgreSQL Day 2016 ITALY la più longeva conferenza dedicata a PostgreSQL in Europa
Modeling avengers – open source technology mix for saving the worldCédric Brun
Planet earth is facing massive challenges: global warming and scarcity of natural resources among others. Those challenges are reaching a level of complexity unknown yet and trying to address those requires deep scientific understanding, real world data, specialized tools, inter-disciplinary collaboration and the ability to evaluate “What If” scenarios.
In collaboration with scientists from INRA (the French National Institute for Agricultural Research) we experienced one of those challenges: the use of natural resources for agricultural activities, especially water consumption. While the scientists insight was required in smart technologies like smart farms, this understanding was required to be expressed at an higher level of abstraction through specific tooling. They felt that providing highly dedicated tools with a small budget would require super powers. To us modeling people it looked like a very good fit for DSL’s (Domain Specific Languages), hence suitable for an experiment : let’s build specific modeling tools for smart farming systems!
This experiment represents a few days of work bringing open-source technologies together: EMF, Xtext, Sirius, Gemoc (a model debugging environment, including specific features for concurrency constraints), OptaPlanner (a constraint satisfaction solver from the JBoss community) and Acceleo, resulting in a collection of Eclipse based tools for farming systems (published on github). Just like in The Avengers, each technology bring its own capability but it is the amalgamation of all of them which lead to amazing power!
The session will start with a demo of the Smart Farming System Tooling, an environment to model, analyze and simulate an agricultural exploitation, biomass growth and water consumption based on user input and open data. Then we will dig deeper in how the technologies are mixed and used, among other questions: which of the textual or graphical syntax is better suited for a given aspect? how can we achieve a “perfect blend” of those syntaxes? how OptaPlanner and EMF can create a powerful synergy? how data from INRA can be structured and fed into the tool?
The talk will then evaluate how useful open-source technologies are in addressing this class of problems and how modeling can be used to support sustainability, enable broader engagement of the community, and facilitate more informed decision-making.
Modeling avengers – open source technology mix for saving the world econ frCédric Brun
Planet earth is facing massive challenges: global warming and scarcity of natural resources among others. Those challenges are reaching a level of complexity unknown yet and trying to address those requires deep scientific understanding, real world data, specialized tools, inter-disciplinary collaboration and the ability to evaluate “What If” scenarios.
In collaboration with scientists from INRA (the French National Institute for Agricultural Research) we experienced one of those challenges: the use of natural resources for agricultural activities, especially water consumption. While the scientists insight was required in smart technologies like smart farms, this understanding was required to be expressed at an higher level of abstraction through specific tooling. They felt that providing highly dedicated tools with a small budget would require super powers. To us modeling people it looked like a very good fit for DSL’s (Domain Specific Languages), hence suitable for an experiment : let’s build specific modeling tools for smart farming systems!
This experiment represents a few days of work bringing open-source technologies together: EMF, Xtext, Sirius, Gemoc (a model debugging environment, including specific features for concurrency constraints), OptaPlanner (a constraint satisfaction solver from the JBoss community) and Acceleo, resulting in a collection of Eclipse based tools for farming systems (published on github). Just like in The Avengers, each technology bring its own capability but it is the amalgamation of all of them which lead to amazing power!
The session will start with a demo of the Smart Farming System Tooling, an environment to model, analyze and simulate an agricultural exploitation, biomass growth and water consumption based on user input and open data. Then we will dig deeper in how the technologies are mixed and used, among other questions: which of the textual or graphical syntax is better suited for a given aspect? how can we achieve a “perfect blend” of those syntaxes? how OptaPlanner and EMF can create a powerful synergy? how data from INRA can be structured and fed into the tool?
No Flex Zone: Empathy Driven DevelopmentDuretti H.
The technology industry has a bad rap. Sexism and misogyny run rampant. Marginalized groups get railroaded. Out-of-touch companies look to make as much money as ruthlessly as possible, all while exploiting others and passing it off as "disruption". Our industry is losing sight of what it could be. Technology, at its heart, has always been aspirational - about dreaming up the impossible and willing it into existence. This talk will discuss what can bring us back from the brink: empathy. Empathy for the people that use the things we make, for our non-technical teammates, and for our fellow engineers.
PHP has its own treasure chest of classic mistakes that surprises even the most seasoned expert : code that dies just by changing its namespace, strpos() that fails to find strings or arrays that changes without touching them. Do that get on your nerves too? Let’s make a list of them, so we can always teach them to the new guys, spot them during code reviews and kick them out of our code once and for all. Come on, you’re not frightening us?
Similar to Geb for Testing Your Grails Application GR8Conf India 2016 (20)
1.Wireless Communication System_Wireless communication is a broad term that i...JeyaPerumal1
Wireless communication involves the transmission of information over a distance without the help of wires, cables or any other forms of electrical conductors.
Wireless communication is a broad term that incorporates all procedures and forms of connecting and communicating between two or more devices using a wireless signal through wireless communication technologies and devices.
Features of Wireless Communication
The evolution of wireless technology has brought many advancements with its effective features.
The transmitted distance can be anywhere between a few meters (for example, a television's remote control) and thousands of kilometers (for example, radio communication).
Wireless communication can be used for cellular telephony, wireless access to the internet, wireless home networking, and so on.
Gen Z and the marketplaces - let's translate their needsLaura Szabó
The product workshop focused on exploring the requirements of Generation Z in relation to marketplace dynamics. We delved into their specific needs, examined the specifics in their shopping preferences, and analyzed their preferred methods for accessing information and making purchases within a marketplace. Through the study of real-life cases , we tried to gain valuable insights into enhancing the marketplace experience for Generation Z.
The workshop was held on the DMA Conference in Vienna June 2024.
Understanding User Behavior with Google Analytics.pdfSEO Article Boost
Unlocking the full potential of Google Analytics is crucial for understanding and optimizing your website’s performance. This guide dives deep into the essential aspects of Google Analytics, from analyzing traffic sources to understanding user demographics and tracking user engagement.
Traffic Sources Analysis:
Discover where your website traffic originates. By examining the Acquisition section, you can identify whether visitors come from organic search, paid campaigns, direct visits, social media, or referral links. This knowledge helps in refining marketing strategies and optimizing resource allocation.
User Demographics Insights:
Gain a comprehensive view of your audience by exploring demographic data in the Audience section. Understand age, gender, and interests to tailor your marketing strategies effectively. Leverage this information to create personalized content and improve user engagement and conversion rates.
Tracking User Engagement:
Learn how to measure user interaction with your site through key metrics like bounce rate, average session duration, and pages per session. Enhance user experience by analyzing engagement metrics and implementing strategies to keep visitors engaged.
Conversion Rate Optimization:
Understand the importance of conversion rates and how to track them using Google Analytics. Set up Goals, analyze conversion funnels, segment your audience, and employ A/B testing to optimize your website for higher conversions. Utilize ecommerce tracking and multi-channel funnels for a detailed view of your sales performance and marketing channel contributions.
Custom Reports and Dashboards:
Create custom reports and dashboards to visualize and interpret data relevant to your business goals. Use advanced filters, segments, and visualization options to gain deeper insights. Incorporate custom dimensions and metrics for tailored data analysis. Integrate external data sources to enrich your analytics and make well-informed decisions.
This guide is designed to help you harness the power of Google Analytics for making data-driven decisions that enhance website performance and achieve your digital marketing objectives. Whether you are looking to improve SEO, refine your social media strategy, or boost conversion rates, understanding and utilizing Google Analytics is essential for your success.
Instagram has become one of the most popular social media platforms, allowing people to share photos, videos, and stories with their followers. Sometimes, though, you might want to view someone's story without them knowing.
2.Cellular Networks_The final stage of connectivity is achieved by segmenting...JeyaPerumal1
A cellular network, frequently referred to as a mobile network, is a type of communication system that enables wireless communication between mobile devices. The final stage of connectivity is achieved by segmenting the comprehensive service area into several compact zones, each called a cell.
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBrad Spiegel Macon GA
Brad Spiegel Macon GA’s journey exemplifies the profound impact that one individual can have on their community. Through his unwavering dedication to digital inclusion, he’s not only bridging the gap in Macon but also setting an example for others to follow.
4. 3 . 1
JACOB AAE MIKKELSEN
Senior Engineer at LEGO
Microservice based architechture on JVM
Previously 4 years at Gennemtænkt IT
Consultant on Groovy and Grails
External Associate Professor - University of Southern
Denmark
@JacobAae
Blogs The Grails Diary
9. 4 . 4
FUNCTIONAL TESTING
Ignores the specifics of the underlying software
component under test.
Whitebox / Greybox
Merely asserts that providing certain input results in
certain output.
Web-application: Programmatically controlling a web
browser to simulate the actions of a user on a web page.
14. 5 . 2
GEB HISTORY
Started in November 2009
Created by Luke Daley
Current project lead Marcin Erdman
15. WHY GEB
jQuery like selector syntax
Power of WebDriver (Easier api)
Robustness of Page Object modeling
Expressiveness of the Groovy language
Integrates well with build systems (Gradle/Maven)
Excellent user manual/documentation
16. 5 . 3
GEB IMPLEMENTATION
Build on top of the WebDriver browser automation library
successor to the Selenium Remote Control (RC) testing
framework.
Selenium RC → JavaScript to interact
WebDriver → native browser drivers
Use JUnit or Spock
17. 5 . 4
WEBDRIVER
Very active development
Stable API and feature set
Verbose
Low level
Not a complete solution
20. 5 . 6
6 . 2
NAVIGATOR
The $() method returns a Navigator object
General format
$ ( < c s s s e l e c t o r > , < i n d e x / r a n g e > , < a t t r i b u t e / t e x t m a t c h e r s > )
21. GEB SELECTORS (1)
Jquery like selecter syntax
/ / m a t c h a l l ' p ' e l e m e n t s o n p a g e
$ ( " p " )
/ / m a t c h t h e f i r s t ' p ' e l e m e n t o n t h e p a g e
$ ( " p " , 0 )
/ / A l l ' d i v ' e l e m e n t s w i t h a t i t l e v a l u e ' s e c t i o n '
$ ( " d i v " , t i t l e : " s e c t i o n " )
/ / m a t c h t h e f i r s t ' d i v ' e l e m e n t t e x t ' s e c t i o n '
$ ( " d i v " , 0 , t e x t : " s e c t i o n " )
/ / m a t c h t h e f i r s t ' d i v ' e l e m e n t w i t h t h e c l a s s ' m a i n '
$ ( " d i v . m a i n " , 0 )
22. 6 . 3
GEB SELECTORS (2)
Text attribute supports regex
/ / A n y d i v w i t h t h e t e x t s t a r t i n g w i h G R 8
$ ( " d i v " , t e x t : ~ / G R 8 . + / )
$ ( " p " , t e x t : s t a r t s W i t h ( " G R 8 " ) )
/ / A n d o t h e r h a n d y p r e d i c a t e s
$ ( " d i v " , c l a s s : c o n t a i n s ( " u i - " ) )
23. 6 . 4
GEB SELECTORS (3)
Selecting returns Navigatorobjects
/ / T h e p a r e n t o f t h e f i r s t d i v
$ ( " d i v " , 0 ) . p a r e n t ( )
/ / A l l t a b l e s w i t h a c e l l s p a c i n g
/ / a t t r i b u t e v a l u e o f 0 t h a t a r e n e s t e d i n a p a r a g r a p h
$ ( " p " ) . f i n d ( " t a b l e " , c e l l s p a c i n g : ' 0 ' )
24. 6 . 56 . 6
CSS SUPPORT
$ ( " t a b l e t r : n t h - c h i l d ( 2 n + 1 ) t d " )
25. 6 . 7
RETRIVING INFORMATION
$ ( " p " ) . t e x t ( ) = = " a "
$ ( " p " ) . t a g ( ) = = " p "
$ ( " p " ) . @ t i t l e = = " a "
$ ( " p " ) . c l a s s e s ( ) = = [ " a " , " p a r a " ]
27. 6 . 86 . 9
SENDING INPUT
i m p o r t o r g . o p e n q a . s e l e n i u m . K e y s
/ / S h o r t h a n d f o r s e n d K e y s ( ) m e t h o d o f W e b D r i v e r .
$ ( " d i v " ) < < " a b c "
$ ( " i n p u t " , n a m e : " f o o " ) < < K e y s . c h o r d ( K e y s . C O N T R O L , " c " )
28. 6 . 10
INTERACTION
Using ActionsAPI from WebDriver is possible.
But Geb provides the interactclosure
29. 6 . 11
CONTROL-CLICKING
i m p o r t o r g . o p e n q a . s e l e n i u m . K e y s
i n t e r a c t {
k e y D o w n K e y s . C T R L
c l i c k $ ( " a . m y L i n k " )
k e y U p K e y s . C T R L
}
30. SIMULATE DRAG-N-DROP
i n t e r a c t {
c l i c k A n d H o l d ( $ ( ' # d r a g g a b l e ' ) )
m o v e B y O f f s e t ( 1 5 0 , 2 0 0 )
r e l e a s e ( )
}
Or easier
i n t e r a c t {
d r a g A n d D r o p B y ( $ ( " # d r a g g a b l e " ) , 1 5 0 , 2 0 0 )
}
31. 6 . 12
MORE INTERACTION WITH FORMS
Consider the following HTML…
< f o r m >
< i n p u t t y p e = " t e x t " n a m e = " g e b " v a l u e = " F u n c t i o n a l " / >
< / f o r m >
The value can be read and written via property notation…
$ ( " f o r m " ) . g e b = = " F u n c t i o n a l "
$ ( " f o r m " ) . g e b = " T e s t i n g "
$ ( " f o r m " ) . g e b = = " T e s t i n g "
These are literally shortcuts for…
$ ( " f o r m " ) . f i n d ( " i n p u t " , n a m e : " g e b " ) . v a l u e ( ) = = " F u n c t i o n a l "
$ ( " f o r m " ) . f i n d ( " i n p u t " , n a m e : " g e b " ) . v a l u e ( " T e s t i n g " )
$ ( " f o r m " ) . f i n d ( " i n p u t " , n a m e : " g e b " ) . v a l u e ( ) = = " T e s t i n g "
32. 6 . 13
VARIABLES AVAILABLE
title
browser
currentUrl
currentWindow
33. 6 . 14
MORE POSSIBILITIES
Uploading files
Downloading files
Interacting with javascript
js object (Example later)
35. GEB STANDALONE EXAMPLE
Lets try to automate:
Searching for GR8Conf India
Click the first link
Hopefully end up on the right homepage
36. 7 . 2
GEB STANDALONE EXAMPLE
g o " h t t p : / / d u c k d u c k g o . c o m "
$ ( ' i n p u t ' , n a m e : ' q ' ) . v a l u e ( " G R 8 C o n f I n d i a " )
$ ( ' i n p u t ' , n a m e : ' q ' ) < < K e y s . E N T E R
w a i t F o r ( 1 0 , 1 ) { $ ( " # l i n k s " ) . d i s p l a y e d }
s l e e p ( 3 0 0 0 ) / / F o r d e m o r e a s o n s
$ ( " h 2 . r e s u l t _ _ t i t l e " ) . f i r s t ( ) . c l i c k ( )
w a i t F o r { t i t l e = " G R 8 C o n f I N - 2 0 1 6 " }
38. SCENARIO
Lets test a CRUD part of a grails application registrering
conference attendees
Lets test the following
1. Goto list of attendees page
2. Create new attendee (incl. invalid data once)
3. Update the attendee
4. Check data is updated
39. 8 . 28 . 3
GEB SPEC BASICS
i m p o r t g e b . s p o c k . G e b S p e c
@ S t e p w i s e / / E n s u r e s t h e t e s t s a r e r u n s e q u e n t i a l l y
c l a s s A t t e n d e e F u n c t i o n a l S p e c e x t e n d s G e b S p e c {
/ / S p o c k s p e c s h e r e
}
40. GEB SPEC (1)
The naive inmaintainable way!
v o i d " G o t o l i s t p a g e - c h e c k i n i t i a l s t a t e " ( ) {
w h e n : " T h e h o m e p a g e i s v i s i t e d "
g o ' / a t t e n d e e / i n d e x '
t h e n :
t i t l e = = " A t t e n d e e L i s t "
}
41. 8 . 4
GEB SPEC (2)
The naive inmaintainable way!
v o i d " C l i c k n e w a t t e n d e e b u t t o n " ( ) {
w h e n :
$ ( " a . c r e a t e " ) . c l i c k ( )
t h e n :
t i t l e = = " C r e a t e A t t e n d e e "
}
42. 8 . 5
GEB SPEC (3)
The naive inmaintainable way!
v o i d " S u b m i t f o r m w i t h e r r o r s " ( ) {
w h e n :
$ ( " b u t t o n . b t n - p r i m a r y " ) . c l i c k ( )
t h e n :
t i t l e = = " C r e a t e A t t e n d e e "
}
43. 8 . 6
GEB SPEC (4)
The naive inmaintainable way!
v o i d " S u b m i t f o r m w i t h n o e r r o r s " ( ) {
w h e n :
$ ( ' f o r m ' ) . n a m e = ' D e e p a k '
$ ( ' f o r m ' ) . e m a i l = ' d e e p a k @ m a i l . o r g '
a n d :
$ ( " b u t t o n . b t n - p r i m a r y " ) . c l i c k ( )
t h e n :
t i t l e = = ' S h o w A t t e n d e e '
$ ( ' d i v . p r o p e r t y - v a l u e ' ) . f i n d { i t . t e x t ( ) = = ' D e e p a k ' }
$ ( ' d i v . p r o p e r t y - v a l u e ' ) . f i n d { i t . t e x t ( ) = = ' d e e p a k @ m a i l . o r g ' }
}
44. 8 . 7
GEB SPEC (5)
The naive inmaintainable way!
v o i d " C l i c k E d i t B u t t o n " ( ) {
w h e n :
$ ( " a . b t n - p r i m a r y " ) . c l i c k ( )
t h e n :
t i t l e = = ' E d i t A t t e n d e e '
}
45. 8 . 8
GEB SPEC (6)
The naive inmaintainable way!
v o i d " U p d a t e A t t e n d e e " ( ) {
w h e n :
$ ( ' f o r m ' ) . n a m e = ' A m i t '
$ ( ' f o r m ' ) . e m a i l = ' a m i t @ m a i l . o r g '
a n d :
$ ( " b u t t o n . b t n - p r i m a r y " ) . c l i c k ( )
t h e n :
t i t l e = = ' S h o w A t t e n d e e '
$ ( ' s p a n . p r o p e r t y - v a l u e ' ) . f i n d { i t . t e x t ( ) = = ' A m i t ' }
$ ( ' s p a n . p r o p e r t y - v a l u e ' ) . f i n d { i t . t e x t ( ) = = ' a m i t @ m a i l . o r g ' }
}
46. 8 . 99 . 1
GEB SPEC - THE BETTER WAY
If we make a few scenarios, there will be
Much duplication
Many places to correct if we change the layout / DOM
49. PAGE OBJECTS
Describes a web page
Url
How to check if we are at the correct place
Content we wish to interact with
.. and how it is found
Helper methods
50. 9 . 4
PAGE OBJECTS
i m p o r t e u . g r 8 c o n f . g r a i l s d e m o . m o d u l e s . N a v i g a t i o n B a r M o d u l e
i m p o r t g e b . P a g e
c l a s s A t t e n d e e S h o w P a g e e x t e n d s P a g e {
s t a t i c u r l = " / a t t e n d e e / s h o w "
s t a t i c a t = { t i t l e = = ~ / S h o w A t t e n d e e / }
s t a t i c c o n t e n t = {
a t t P r o p { $ ( ' s p a n . p r o p e r t y - l a b e l ' ) }
n a m e { a t t P r o p . f i n d { i t . t e x t ( ) = = ' N a m e ' } . n e x t ( ) . t e x t ( ) }
e m a i l { a t t P r o . f i n d { i t . t e x t ( ) = = ' E m a i l ' } . n e x t ( ) . t e x t ( ) }
e d i t B u t t o n { $ ( " a . b t n - p r i m a r y " ) }
}
}
51. 9 . 59 . 6
CONTENT CLOSURE
s t a t i c c o n t e n t = {
i n f o ( r e q u i r e d : f a l s e ) { $ ( " d i v . i n f o " ) }
m e s s a g e ( w a i t : f a l s e ) { $ ( " d i v . m e s s a g e " ) }
}
53. MODULES
i m p o r t g e b . M o d u l e
c l a s s N a v i g a t i o n B a r M o d u l e e x t e n d s M o d u l e {
s t a t i c b a s e = { $ ( ' n a v . n a v b a r ' ) }
s t a t i c c o n t e n t = {
h o m e ( r e q u i r e d : f a l s e ) { $ ( ' a . h o m e ' ) }
l i s t A t t e n d e e ( r e q u i r e d : f a l s e ) { $ ( ' a . l i s t ' ) }
n e w A t t e n d e e ( r e q u i r e d : f a l s e ) { $ ( ' a . c r e a t e ' ) }
}
}
54. 9 . 89 . 9
MODULES
s t a t i c c o n t e n t = {
/ / L i k e t h i s , t h e m o d u l e d o e s n o t n e e d a b a s e
/ / f o r m { m o d u l e N a v i g a t i o n B a r M o d u l e , $ ( ' n a v . n a v b a r ' ) }
f o r m { m o d u l e N a v i g a t i o n B a r M o d u l e }
}
55. MODULE FOR REPEATED CONTENT
IN A PAGE
i m p o r t g e b . M o d u l e
c l a s s A t t e n d e e L i s t I t e m M o d u l e e x t e n d s M o d u l e {
s t a t i c c o n t e n t = {
d a t a { $ ( " t d " , i t ) }
n a m e { d a t a ( 0 ) . t e x t ( ) }
e m a i l { d a t a ( 1 ) . t e x t ( ) }
n a t i o n a l i t y { d a t a ( 2 ) . t e x t ( ) }
d a t e C r e a t e d { d a t a ( 3 ) . t e x t ( ) }
l a s t U p d a t e d { d a t a ( 4 ) . t e x t ( ) }
}
}
56. 9 . 10
MODULE FOR REPEATED CONTENT
IN A PAGE
AttendeeListPage.groovy
s t a t i c c o n t e n t = {
m e n u b a r { m o d u l e N a v i g a t i o n B a r M o d u l e }
a t t e n d e e s { m o d u l e L i s t A t t e n d e e L i s t I t e m M o d u l e ,
$ ( " t a b l e t r " ) . t a i l ( ) }
}
57. 9 . 119 . 12
MODULE FOR REPEATED CONTENT
IN A PAGE
w h e n :
t o A t t e n d e e L i s t P a g e
t h e n :
a t t e n d e e s * . n a m e . c o n t a i n s ( ' B u r t B e c k w i t h ' )
58. GEB SPEC - STRUCTURED (1)
Lets try to restructure the ugly spec from before
v o i d " G o t o l i s t p a g e - c h e c k i n i t i a l s t a t e " ( ) {
w h e n :
t o A t t e n d e e I n d e x P a g e
t h e n :
a t A t t e n d e e I n d e x P a g e
}
59. 9 . 139 . 14
GEB SPEC - STRUCTURED (2)
v o i d " C l i c k n e w a t t e n d e e b u t t o n " ( ) {
w h e n :
m e n u b a r . n e w A t t e n d e e . c l i c k ( )
t h e n :
a t A t t e n d e e C r e a t e P a g e
}
60. 9 . 15
GEB SPEC - STRUCTURED (3)
v o i d " S u b m i t f o r m w i t h e r r o r s " ( ) {
w h e n :
s u b m i t B u t t o n . c l i c k ( )
t h e n :
a t A t t e n d e e C r e a t e P a g e
}
61. GEB SPEC - STRUCTURED (4)
v o i d " S u b m i t f o r m w i t h n o e r r o r s " ( ) {
w h e n :
f o r m . n a m e = ' D e e p a k '
f o r m . e m a i l = ' d e e p a k @ m a i l . o r g '
a n d :
s u b m i t B u t t o n . c l i c k ( )
t h e n :
a t A t t e n d e e S h o w P a g e
n a m e = = ' D e e p a k '
e m a i l = = ' d e e p a k @ m a i l . o r g '
}
62. 9 . 169 . 17
GEB SPEC - STRUCTURED (5)
v o i d " C l i c k E d i t B u t t o n " ( ) {
w h e n :
e d i t B u t t o n . c l i c k ( )
t h e n :
a t A t t e n d e e E d i t P a g e
}
63. GEB SPEC - STRUCTURED (6)
v o i d " U p d a t e A t t e n d e e " ( ) {
w h e n :
f o r m . n a m e = ' A m i t '
f o r m . e m a i l = ' a m i t @ s o m e m a i l . c o m '
a n d :
u p d a t e B u t t o n . c l i c k ( )
t h e n :
a t A t t e n d e e S h o w P a g e
n a m e = = ' A m i t '
e m a i l = = ' a m i t @ s o m e m a i l . c o m '
}
64. 9 . 18
STANDALONE REVISITED
t o D u c k D u c k G o P a g e
i n p u t F i e l d < < " G R 8 C o n f I n d i a "
s u b m i t ( )
w a i t F o r ( 1 0 , 0 . 5 ) {
a t D u c k D u c k G o R e s u l t P a g e
}
s l e e p ( 3 0 0 0 ) / / F o r d e m o r e a s o n s
c l i c k L i n k ( 0 )
w a i t F o r {
a t G R 8 C o n f I n d i a P a g e
}
65. 9 . 19
STANDALONE REVISITED
c l a s s D u c k D u c k G o P a g e e x t e n d s g e b . P a g e {
s t a t i c u r l = " h t t p : / / d u c k d u c k g o . c o m "
s t a t i c a t = { t i t l e = = ~ / D u c k D u c k G o / }
s t a t i c c o n t e n t = {
i n p u t F i e l d { $ ( ' i n p u t ' , n a m e : ' q ' ) }
}
d e f s u b m i t ( ) {
i n p u t F i e l d < < K e y s . E N T E R
}
}
67. GEB AND GRAILS 2.X
Must install plugin in BuildConfig.groovy
d e p e n d e n c i e s {
. . .
t e s t ( " o r g . s e l e n i u m h q . s e l e n i u m : s e l e n i u m - s u p p o r t : 2 . 4 5 . 0 " )
t e s t ( " o r g . s e l e n i u m h q . s e l e n i u m : s e l e n i u m - f i r e f o x - d r i v e r : 2 . 4 5 . 0 " )
t e s t " o r g . g e b i s h : g e b - s p o c k : 0 . 1 0 . 0 "
}
p l u g i n s {
. . .
t e s t " o r g . g r a i l s . p l u g i n s : g e b : 0 . 1 0 . 0 "
}
68. 10 . 210 . 3
GEB TESTS IN GRAILS 2.X
Tests placed in test/functionalfolder
Running the tests
g r a i l s t e s t - a p p f u n c t i o n a l :
69. GEB AND GRAILS 3
Geb is default in build.gradle
d e p e n d e n c i e s {
. . .
t e s t C o m p i l e " o r g . g r a i l s . p l u g i n s : g e b "
/ / N o t e : I t i s r e c o m m e n d e d t o u p d a t e t o a m o r e r o b u s t d r i v e r
/ / ( C h r o m e , F i r e f o x e t c . )
t e s t R u n t i m e ' o r g . s e l e n i u m h q . s e l e n i u m : s e l e n i u m - h t m l u n i t - d r i v e r : 2 . 4 4 . 0
}
70. 10 . 4
GEB TESTS IN GRAILS 3
Creating Geb Spec
g r a i l s c r e a t e - f u n c t i o n a l - t e s t M y G e b S c e n a r i o
Placing the test in src/integration-test/groovy
Running the tests
g r a i l s t e s t - a p p - i n t e g r a t i o n
71. 10 . 5
GENERATED CLASS
@ I n t e g r a t i o n
@ R o l l b a c k
c l a s s M a n y A t t e n d e e s S p e c e x t e n d s G e b S p e c {
v o i d " t e s t s o m e t h i n g " ( ) {
w h e n : " T h e h o m e p a g e i s v i s i t e d "
g o ' / '
t h e n : " T h e t i t l e i s c o r r e c t "
$ ( ' t i t l e ' ) . t e x t ( ) = = " W e l c o m e t o G r a i l s "
}
}
72. 10 . 610 . 7
INTERACTING WITH APPLICATION
When some functionality is needed that is not exposed
through the browser, it can be necessary to interact with the
application under test.
73. GRAILS 2.5
Tests not running in same JVM
Done with remote-control plugin
Send a closure for execution in application
c o m p i l e " : r e m o t e - c o n t r o l : 2 . 0 "
74. 10 . 810 . 9
REMOTE CONTROL
s e t u p : ' C r e a t e s o m e i t e m n o t a v a i l a b l e t h r o u g h G U I '
d e f i d = r e m o t e {
I t e m i t e m = n e w I t e m ( n a m e : " M y I t e m " )
i t e m . s a v e ( )
i t e m . i d
}
75. 10 . 10
GRAILS 3.0
Application is in same jvm
Interaction is possible directly
Tests run as integration tests
76. INTERACTING WITH APPLICATION
v o i d " T e s t P a g i n a t i o n i s s h o w n w i t h 1 5 a t t e n d e e s " ( ) {
s e t u p :
A t t e n d e e . w i t h N e w T r a n s a c t i o n {
1 5 . t i m e s {
n e w A t t e n d e e ( n a m e : " N $ i t " , e m a i l : " m $ i t @ t . d k " ) . s a v e ( )
}
}
w h e n :
t o A t t e n d e e I n d e x P a g e
t h e n :
h a s P a g i n a t i o n ( )
}
77. 10 . 1110 . 12
INTERACTING WITH APPLICATION
s t a t i c c o n t e n t = {
m e n u b a r { m o d u l e N a v i g a t i o n B a r M o d u l e }
p a g i n a t i o n ( r e q u i r e d : f a l s e ) { $ ( ' s p a n . c u r r e n t S t e p ' ) }
}
b o o l e a n h a s P a g i n a t i o n ( ) {
p a g i n a t i o n . t e x t ( )
}
79. 11 . 2
GEBCONFIG
Configuration for Geb is placed in GebConfig.groovy
In Grails 3, place it in ´src/integration-test/groovy`
http://www.gebish.org/manual/current/configuration.htm
82. 11 . 411 . 5
DRIVER
It is possible to configure the browser used.
build.gradle
c o m p i l e ' o r g . s e l e n i u m h q . s e l e n i u m : s e l e n i u m - c h r o m e - d r i v e r : 2 . 4 9 . 0 '
c o m p i l e ' o r g . s e l e n i u m h q . s e l e n i u m : s e l e n i u m - f i r e f o x - d r i v e r : 2 . 4 9 . 0 '
83. FIREFOX
GebConfig.groovy
i m p o r t o r g . o p e n q a . s e l e n i u m . f i r e f o x . F i r e f o x P r o f i l e
i m p o r t o r g . o p e n q a . s e l e n i u m . f i r e f o x . F i r e f o x D r i v e r
d r i v e r = {
F i r e f o x P r o f i l e p r o f i l e = n e w F i r e f o x P r o f i l e ( )
p r o f i l e . s e t P r e f e r e n c e ( " b r o w s e r . d o w n l o a d . f o l d e r L i s t " , 2 )
p r o f i l e . s e t P r e f e r e n c e ( " b r o w s e r . d o w n l o a d . d i r " , " / t m p " )
p r o f i l e . s e t P r e f e r e n c e (
" b r o w s e r . h e l p e r A p p s . n e v e r A s k . s a v e T o D i s k " , " t e x t / c s v " )
d e f d r i v e r I n s t a n c e = n e w F i r e f o x D r i v e r ( p r o f i l e )
d r i v e r I n s t a n c e . m a n a g e ( ) . w i n d o w ( ) . m a x i m i z e ( )
d r i v e r I n s t a n c e
}
84. 11 . 611 . 7
CHROME
Needs ChromeDriver downloaded
Pretty fast and stable
85. CHROME (1)
GebConfig.groovy
p r i v a t e S t r i n g d r i v e r L o c a t i o n D e p e n d i n g O n O p e r a t i n g S y s t e m ( ) {
S t r i n g o s = S y s t e m . g e t P r o p e r t y ( " o s . n a m e " ) . t o L o w e r C a s e ( ) ;
d e f l o c = " h t t p : / / c h r o m e d r i v e r . s t o r a g e . g o o g l e a p i s . c o m / 2 . 2 0 "
i f ( o s . c o n t a i n s ( ' m a c ' ) ) {
r e t u r n " $ { l o c } / c h r o m e d r i v e r _ m a c 3 2 . z i p "
}
i f ( o s . c o n t a i n s ( ' w i n ' ) ) {
r e t u r n " $ { l o c } / c h r o m e d r i v e r _ w i n 3 2 . z i p "
}
r e t u r n " $ { l o c } / c h r o m e d r i v e r _ l i n u x 6 4 . z i p "
}
86. 11 . 8
CHROME (2)
GebConfig.groovy
p r i v a t e v o i d d o w n l o a d D r i v e r ( F i l e f i l e , S t r i n g p a t h ) {
i f ( ! f i l e . e x i s t s ( ) ) {
d e f a n t = n e w A n t B u i l d e r ( )
a n t . g e t ( s r c : p a t h , d e s t : ' d r i v e r . z i p ' )
a n t . u n z i p ( s r c : ' d r i v e r . z i p ' , d e s t : f i l e . p a r e n t )
a n t . d e l e t e ( f i l e : ' d r i v e r . z i p ' )
a n t . c h m o d ( f i l e : f i l e , p e r m : ' 7 0 0 ' )
}
}
87. 11 . 9
CHROME (3)
GebConfig.groovy
d e f c h r o m e D r i v e r = n e w F i l e ( ' b u i l d / d r i v e r s / c h r o m e / c h r o m e d r i v e r ' )
d o w n l o a d D r i v e r ( c h r o m e D r i v e r ,
d r i v e r L o c a t i o n D e p e n d i n g O n O p e r a t i n g S y s t e m ( ) )
S y s t e m . s e t P r o p e r t y ( ' w e b d r i v e r . c h r o m e . d r i v e r ' ,
c h r o m e D r i v e r . a b s o l u t e P a t h )
d r i v e r = {
d e f d r i v e r I n s t a n c e = n e w C h r o m e D r i v e r ( )
d e f b r o w s e r W i n d o w = d r i v e r I n s t a n c e . m a n a g e ( ) . w i n d o w ( )
/ / w i d t h , h e i g h t
b r o w s e r W i n d o w . s i z e = n e w D i m e n s i o n ( 1 0 0 0 , 2 5 0 0 )
b r o w s e r W i n d o w . p o s i t i o n = n e w P o i n t ( 0 , 0 )
d r i v e r I n s t a n c e
}
88. 11 . 10
WAITING
GebConfig.groovy
w a i t i n g {
t i m e o u t = 1 0
r e t r y I n t e r v a l = 0 . 5
}
b a s e N a v i g a t o r W a i t i n g = t r u e
a t C h e c k W a i t i n g = t r u e
89. 11 . 11
USING WAITING
< d i v c l a s s = " f a d e - m e - i n " s t y l e = " d i s p l a y : n o n e " >
H i - a r e y o w a i t i n g f o r m e ?
< / d i v >
< s c r i p t >
$ ( ' d i v . f a d e - m e - i n ' ) . d e l a y ( 3 0 0 0 ) . s l i d e D o w n ( ) ;
< / s c r i p t >
s t a t i c c o n t e n t = {
f a d e I n M e s s a g e { $ ( ' d i v . f a d e - m e - i n ' ) }
}
t h e n :
w a i t F o r {
f a d e I n M e s s a g e . t e x t ( ) = = ' H i - a r e y o w a i t i n g f o r m e ? '
}
90. 11 . 12
PAUSING GEB
p r i v a t e v o i d p a u s e ( ) {
j s . e x e c " " " ( f u n c t i o n ( ) {
w i n d o w . _ _ g e b P a u s e d = t r u e ;
v a r d i v = d o c u m e n t . c r e a t e E l e m e n t ( " d i v " ) ;
d i v . s e t A t t r i b u t e ( ' s t y l e ' , " p o s i t i o n : a b s o l u t e ; t o p : 0 p x ;
z - i n d e x : 3 0 0 0 ; p a d d i n g : 1 0 p x ; b a c k g r o u n d - c o l o r : r e d ; ) ;
v a r b u t t o n = d o c u m e n t . c r e a t e E l e m e n t ( " b u t t o n " ) ;
b u t t o n . i n n e r H T M L = " U n p a u s e G e b " ;
b u t t o n . o n c l i c k = f u n c t i o n ( ) {
w i n d o w . _ _ g e b P a u s e d = f a l s e ;
}
d i v . a p p e n d C h i l d ( b u t t o n ) ;
d o c u m e n t . g e t E l e m e n t s B y T a g N a m e ( " b o d y " ) [ 0 ] . a p p e n d C h i l d ( d i v ) ;
} ) ( ) ; " " "
w a i t F o r ( 3 0 0 ) { ! j s . _ _ g e b P a u s e d }
}
91. 11 . 1311 . 14
PAUSING GEB
w h e n :
p a u s e ( ) / / P a u s e G e b u n t i l b u t t o n p r e s s e d
93. 12 . 2
TEST REPORTS
Nicely formatted
Spock power-assert format
94. SCREENSHOTS
Screenshots and HTML from end of each test:
Extend from GebReportingSpec
c l a s s A t t e n d e e F u n c t i o n a l S p e c e x t e n d s G e b R e p o r t i n g S p e c
GebConfig.groovy
r e p o r t s D i r = n e w F i l e ( " b u i l d / g e b - r e p o r t s " )
95. 12 . 312 . 4
AD-HOC SCREENSHOTS
r e p o r t " W h e n - f o r m - i s - j u s t - f i l l e d "
Saves a report in reportsDir
Numbered in increasing order
97. 13 . 2
EXECUTING JAVASCRIPT
Clicking a button that is hidden will create a
ElementNotVisibleException
< f i e l d s e t c l a s s = " w e l l " s t y l e = " d i s p l a y : n o n e " >
< g : l i n k c l a s s = " b t n " a c t i o n = " i n d e x " > L i s t < / g : l i n k >
< / f i e l d s e t >
98. 13 . 3
EXECUTING JAVASCRIPT
J a v a s c r i p t E x e c u t o r e x e c u t o r = ( J a v a s c r i p t E x e c u t o r ) d r i v e r
e x e c u t o r . e x e c u t e S c r i p t ( ' j Q u e r y ( " . w e l l " ) . s h o w ( ) ; ' )
99. 13 . 4
WRAPPING JAVASCRIPT
d e f j s ( S t r i n g s c r i p t ) {
( d r i v e r a s J a v a s c r i p t E x e c u t o r ) . e x e c u t e S c r i p t ( s c r i p t )
}
j s ( ' j Q u e r y ( " . w e l l " ) . s h o w ( ) ; ' )
100. 13 . 5
JQUERY SHORTHAND
$ ( " d i v # a " ) . j q u e r y . m o u s e o v e r ( )
$ ( " # a " ) . j q u e r y . t r i g g e r ( ' m o u s e o v e r ' )