├── README.md └── tests ├── Git └── comandos_git.md ├── Bundler ├── 01-introducao_bundler.md ├── 02-opcoes_extras_bundle_install.md ├── 03-opcoes_extras_bundle_update.md ├── 04-comandos_extras_bundle_config.md └── comandos_bundler.md ├── Calabash └── comandos_calabash.md ├── Capybara ├── 01-introducao.md ├── 02-instalando_drivers.md ├── 03-configurando_projeto.md ├── 04-acessando_url.md ├── 05-buscando_elementos.md ├── 06-realizando_acoes.md ├── 07-validando_elementos.md ├── 08-validacoes_com_rspec_matchers.md ├── 09-janelas_modal_alerts_iframe.md ├── 10-metodos_screenshots.md ├── 11-comandos_javascript.md ├── capybara.md └── comandos_capybara.md ├── CircleCi └── comandos_circleci.md ├── Codeship └── comandos_codeship.md ├── ConfiguracaoAndroid ├── configuracao_android.md ├── configuracao_android_linux.md ├── configuracao_android_mac.md └── configuracao_android_windows.md ├── ConfiguracaoRuby ├── configuracao_ruby.md ├── instalando_ruby_linux.md ├── instalando_ruby_mac.md └── instalando_ruby_windows.md ├── Cucumber ├── 01-introducao_cucumber.md ├── 02-instalacao_cucumber.md ├── 03-given_when_then_but_and.md ├── 04-background.md ├── 05-hooks.md ├── 06-chamando_steps.md ├── 07-esquema_cenario.md ├── 08-tags.md ├── 09-data_table.md ├── 10-cucumberyml.md └── comandos_cucumber.md ├── Docker └── comandos_docker.md ├── Gitlabci └── comandos_gitlabci.md ├── Httparty └── comandos_httparty.md ├── Jenkins └── comandos_jenkins.md ├── JsonSchema └── comandos_json_schema.md ├── Rake └── comandos_rake.md ├── Rspec └── comandos_rspec.md ├── Ruby ├── RubyBasico │ ├── 01-hello_world.md │ ├── 02-entrada_e_saida.md │ ├── 03-variaveis_e_primitivos.md │ ├── 04-comentarios.md │ ├── 05-string_e_interpolacao.md │ ├── 06-coercao.md │ ├── 07-operadores_aritimeticos.md │ ├── 08-operadores_relacionais.md │ ├── 09-operador_de_atribuicao.md │ ├── 10-estruturas_condicionais.md │ ├── 11-operadores_logicos.md │ ├── 12-estrutura_de_repeticao.md │ ├── 13-vetores_e_arrays.md │ ├── 14-hashes.md │ ├── 15-simbolos.md │ ├── 16-iterador_each.md │ └── 17-operadores_de_intervalo.md ├── RubyOrientadoObjeto │ ├── 01-classe.md │ ├── 02-metodos.md │ ├── 03-definindo_atributos.md │ ├── 04-initialize.md │ ├── 05-herança.md │ ├── aula10.md │ ├── aula11.md │ ├── aula12.md │ ├── aula13.md │ ├── aula14.md │ ├── aula6.md │ ├── aula7.md │ ├── aula8.md │ └── aula9.md └── comandos_ruby.md ├── SeleniumWebdriver └── comandos_selenium_webdriver.md ├── SitePrism ├── 01-introducao.md ├── 02-instalando_siteprism.md ├── 03-setando_urls.md ├── 04-elementos.md ├── 05-lista_de_elementos.md ├── 06-ajax.md ├── 07-sessoes.md ├── 08-iframe.md ├── 09-melhorando_pageobjects.md └── comandos_siteprism.md ├── Travisci └── comandos_travis.md ├── Watir └── comandos_watir.md └── apks ├── PreciseUnitConversion.apk ├── TrianguloApp.apk ├── calculadora.apk ├── com.orgzly_60.apk ├── org.wikipedia_2.5.195-r-2017-04-21-195_minAPI16(arm64-v8a,armeabi,armeabi-v7a,mips,x86,x86_64)(nodpi)_apkmirror.com.apk └── teste.apk /README.md: -------------------------------------------------------------------------------- 1 | # best_archer 2 | Criei esse repositório para reunir todos os comandos das principais ferramentas de automação em Ruby. 3 | 4 | Então eu estou juntando referências de vários posts que encontro na internet. 5 | 6 | E também da própria documentação dos frameworks. 7 | 8 | ## Configuração: 9 | 10 | 1. [Configuração Ruby](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/configuracao_ruby.md); 11 | 3. [Configuração Android](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoAndroid/configuracao_android.md); 12 | 13 | ## Básico: 14 | 15 | 1. [Ruby Básico](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/comandos_ruby.md); 16 | 2. [Rspec Básico](https://github.com/brunobatista25/best_archer/blob/master/tests/Rspec/comandos_rspec.md); (EM BREVE...) 17 | 18 | ## BDD com: 19 | 20 | 1. [Comandos Cucumber](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/comandos_cucumber.md); 21 | 22 | ## Automação web: 23 | 24 | 1. [Comandos Capybara](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/comandos_capybara.md); 25 | 2. [Comandos SitePrism](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/comandos_siteprism.md); 26 | 3. [Comandos Watir](https://github.com/brunobatista25/best_archer/blob/master/tests/Watir/comandos_watir.md); (EM BREVE...) 27 | 4. [Comandos SeleniumWebDriver](https://github.com/brunobatista25/best_archer/blob/master/tests/SeleniumWebdriver/comandos_selenium_webdriver.md); (EM BREVE...) 28 | 29 | ## Automação de Api: 30 | 31 | 1. [Comandos Httparty](https://github.com/brunobatista25/best_archer/blob/master/tests/Httparty/comandos_httparty.md); (EM BREVE...) 32 | 2. [Teste de Contrato com Json-Schema](https://github.com/brunobatista25/best_archer/blob/master/tests/JsonSchema/comandos_json_schema.md); (EM BREVE...) 33 | 34 | ## Mobile: 35 | 36 | 1. [Comandos Appium](https://github.com/brunobatista25/best_archer/blob/master/tests/Appium/comandos_appium.md); (EM BREVE...) 37 | 2. [Comandos Calabash](https://github.com/brunobatista25/best_archer/blob/master/tests/Calabash/comandos_calabash.md); (EM BREVE...) 38 | 39 | ## Outros: 40 | 41 | 1. [Comandos Git](https://github.com/brunobatista25/best_archer/blob/master/tests/%20Git/comandos_git.md); 42 | 2. [Comandos Bundler](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/01-introducao_bundler.md); 43 | 3. [Comandos Rake](https://github.com/brunobatista25/best_archer/blob/master/tests/Rake/comandos_rake.md); (EM BREVE...) 44 | 45 | ## DEVOPS 46 | 47 | 1. [Comandos Codeship](https://github.com/brunobatista25/best_archer/blob/master/tests/Codeship/comandos_codeship.md); 48 | 2. [Comandos Jenkis](https://github.com/brunobatista25/best_archer/blob/master/tests/Jenkins/comandos_jenkins.md); (EM BREVE...) 49 | 3. [Comandos CircleCi](https://github.com/brunobatista25/best_archer/blob/master/tests/CircleCi/comandos_circleci.md); (EM BREVE...) 50 | 4. [Comandos TravisCi](https://github.com/brunobatista25/best_archer/blob/master/tests/Travisci/comandos_travis.md); (EM BREVE...) 51 | 5. [Comandos GitLabCi](https://github.com/brunobatista25/best_archer/blob/master/tests/Gitlabci/comandos_gitlabci.md); (EM BREVE...) 52 | 6. [Comandos Docker](https://github.com/brunobatista25/best_archer/blob/master/tests/Docker/comandos_docker.md); (EM BREVE...) 53 | 54 | ## TDD com: 55 | 1. [Comandos Rspec](https://github.com/brunobatista25/best_archer/blob/master/tests/Rspec/comandos_rspec.md); (EM BREVE...) 56 | 57 | ## Projetos prontos para exemplo: 58 | 59 | 1. [Projeto Cucumber + Capybara + SitePrism + Ruby](https://github.com/brunobatista25/capybara_cucumber); 60 | 61 | 2. [Projeto Rspec + Capybara + SitePrism + Ruby](https://github.com/brunobatista25/capybara_rspec); 62 | 63 | 3. [Projeto Httparty + Cucumber + Ruby](https://github.com/brunobatista25/test_api_httparty_cucumber); 64 | 65 | ## Sites para fazer automação Web/API/Mobile: 66 | 67 | 1. [Site para treinar Automação Web](https://automacaocombatista.herokuapp.com/); 68 | 69 | 2. [Api para treinar Automação de API](https://automacaocombatista.herokuapp.com/); 70 | 71 | LINK PARA DOCUMENTAÇÃO DA API: https://app.apiary.io/apidetarefas 72 | 73 | 3. [Site com o IPA para treinar Automação Mobile](https://iosninja.io/ipa-library); 74 | 75 | 4. [Site com o APK para treinar Automação Mobile](https://apkpure.com/br/app); 76 | 77 | Quem quiser ajudar a contribuir nesse projeto será bem vindo! 78 | 79 | Qualquer coisa meu email é brunobatista101@gmail.com 80 | 81 | Até mais jovens! 82 | 83 | 84 | erros windows utf 8 85 | painel de controle 86 | regiao 87 | aba administrativo 88 | alterar localidade do sistema 89 | marcar checkbox Beta: usar unicode UTF-8 para suporte de linguagem mundial 90 | -------------------------------------------------------------------------------- /tests/ Git/comandos_git.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | Nesta sessão serão apresentados alguns dos principais comandos Git no desenvolvimento e manutenção de software. Primeiramente será necessário baixar o git em seu computador, abaixo seguem os instaladores e seus respectivos sistemas operacionais: 4 | 5 | * [Instalador Windows](https://git-scm.com/download/win); 6 | * [Instalador Linux/Unix](https://git-scm.com/download/linux); 7 | * [Instalador MAC OS X](https://git-scm.com/download/mac); 8 | 9 | --- 10 | ## Configurando a sua Identidade Git 11 | 12 | O primeiro passo na configuração do Git é definir suas credenciais de acesso aos repositórios, isso é importante ao enviar e baixar as modificações em seu código. O comando básico para isto é este: 13 | 14 | ``` 15 | $ git config --global user.name "Eduardo Pacheco" 16 | $ git config --global user.email eduardo.pacheco@aprendendogit.com.br 17 | ``` 18 | Lembrando que podemos utilizar o comando acima sem o parâmetro '--global' para projetos específicos, este é um parâmetro apenas pra facilitar o acesso aos projetos de um só repositório. 19 | 20 | **_Obs.: Existem algumas outras configurações como a escolha do editor de texto padrão, ferramenta para a solução de conflitos, entre outras que podem ser visualizadas através deste link: [Configurações iniciais Git](https://git-scm.com/book/pt-br/v1/Primeiros-passos-Configura%C3%A7%C3%A3o-Inicial-do-Git)_** 21 | 22 | Após a instalação do Git podemos começar a utilizar a ferramenta de duas formas básicas. Estas são criar um novo repositório a partir de algum projeto local ou baixar algum repositório remoto já pré-existente. Os comandos para estes dois casos iremos explicar no tópico seguinte. 23 | 24 | --- 25 | ## Iniciando com o Git 26 | 27 | O primeiro comando apresentado neste tópico será o de criar um repositório a partir de um projeto local, para isto vá até o diretório onde o projeto esta e execute o seguinte comando: 28 | 29 | ``` 30 | git init 31 | ``` 32 | Assim como podemos criar um repositório a partir de um projeto local, podemos também baixar uma cópia de um repositório remoto a partir deste comando: 33 | ``` 34 | git clone /caminho/do/repositório 35 | ``` 36 | O comando para realizar o clone de um servidor remoto utilizando credenciais de acesso a este servidor se dá através deste comando: 37 | ``` 38 | git clone username@ip_do_servidor:/path/to/repo.git 39 | ``` 40 | --- 41 | ## Entendendo o Fluxo de Trabalho do Git 42 | 43 | O fluxo de trabalho do Git se resume em três etapas, sendo elas (Apresentas da direita pra esquerda na imagem abaixo): 44 | 45 | 1. **Working Directory/Work Tree:** _Onde esta armazenado a cópia do repositório no seu computador e onde os arquivos serão modificados;_ 46 | 2. **Index/Stage:** _Onde estarão os arquivos já modificados e passíveis de serem enviados ou não para o servidor remoto;_ 47 | 2. **HEAD -- Repository:** _Onde esta a versão final dos arquivos que serão enviados para o servidor._ 48 | 49 | ![alt text](https://backlog.com/git-tutorial/en/img/post/intro/capture_intro1_4_1.png) 50 | 51 | ### 1. Adicionando arquivos ao diretório remoto 52 | 53 | Após realizarmos a configuração do Git e fazermos o clone de um repositório na qual queremos realizar alterações, o próximo passo é enviar as modificações realizadas para o resto do time, para isto existem alguns passos, o primeiro é verificar os arquivos modificados através do comando: 54 | 55 | ``` 56 | git status 57 | ``` 58 | O retorno no console deverá ser algo parecido com isto: 59 | 60 | ```shell 61 | > git status 62 | On branch comandos_github 63 | Your branch is up-to-date with 'origin/github'. 64 | Changes not staged for commit: 65 | (use "git add ..." to update what will be committed) 66 | (use "git checkout -- ..." to discard changes in working directory) 67 | 68 | modified: github.md 69 | 70 | no changes added to commit (use "git add" and/or "git commit -a") 71 | ``` 72 | No exemplo acima temos um arquivo para ser enviado ao servidor remoto. O próximo passo é inserir o(os) arquivos ao **Index**, o comando será esse: 73 | 74 | ``` 75 | git add 76 | ``` 77 | Ou caso queiramos enviar todos os arquivos de uma só vez basta inserir um ponto após a tag 'add': 78 | ``` 79 | git add . 80 | ``` 81 | 82 | Para confirmar que queremos que estas modificações sejam enviadas para o servidor remoto, temos que 'commitar', ou seja confirmar o envio: 83 | 84 | ``` 85 | git commit -m "Criando tutorial Git" 86 | ``` 87 | **_Obs.: O parâmetro '-m' significa a mensagem do commit, ou seja, uma breve descrição sobre o que você acabou de inserir/alterar no código_** 88 | 89 | Imagine agora que você errou na mensagem do commit ou simplesmente quer se desfazer do último realizado, existe alguma forma de fazer isto? Sim, através do parâmetro **--amend**: 90 | ``` 91 | git commit --amend 92 | ``` 93 | 94 | Pronto! Já está tudo no servidor remoto então e todos podem utilizar o meu código? ÉÉÉÉÉÉ..Ainda não :sweat_smile: 95 | 96 | Precisamos enviar as modificações para o servidor remoto com o comando **push**: 97 | 98 | ``` 99 | git push origin master 100 | ``` 101 | 102 | Sendo que podemos também alterar a branch\* na qual iremos enviar as modificações. No exemplo acima enviamos as modificações direto para a branch principal (master) mas poderíamos enviar para a branch **github** por exemplo: 103 | 104 | ``` 105 | git push origin github 106 | ``` 107 | 108 | ### Mas o que são Branches?! 109 | 110 | Diferente de outros controladores de versão, o Git tem como diferencial criar 'Cópias de Repositórios' para dentro de sua máquina. Ou seja, criamos a cópia de um repositório estável e em cima dela desenvolvemos as features para posteriormente serem inseridas nesta versão estável do repositório. 111 | 112 | ![alt text](https://grapefruitgames.files.wordpress.com/2013/05/unitygitdiagram.png) 113 | 114 | Normalmente a branch principal de um projeto é a branch **master**. Não é uma prática aceitável realizar **commits** e dar **push** diretamente nesta branch. Por isso o recomendável é criar branches locais e após isso realizar a inserção do que foi desenvolvido na **master**. 115 | 116 | Para saber a branch na qual estamos trabalhando o comando é este: 117 | ``` 118 | git branch 119 | ``` 120 | Este comando retornará as branches que temos localmente e marcará com um asterisco qual é a branch atual. 121 | 122 | Podemos mudar a branch quando bem entendermos através do comando **checkout**: 123 | 124 | ``` 125 | git checkout nome_da_branch 126 | ``` 127 | 128 | Ou criarmos uma nova branch local através do comando: 129 | 130 | ``` 131 | git checkout -b nome_da_nova_branch 132 | ``` 133 | 134 | O comando git checkout pode ser utilizado não apenas no âmbito de branches mas também no de arquivos. Por exemplo, fizemos modificações em um arquivo chamado _github.txt_ porém este arquivo já foi criado no repositório remoto com as mesmas modificações, para descartamos o que fizemos e atualizarmos com a versão do repositório remoto basta executarmos o comando: 135 | 136 | ``` 137 | git checkout -- nome_do_arquivo 138 | ``` 139 | 140 | **_Obs.: Isto irá substituir apenas os arquivos que ainda não foram commitados. Ou seja, os que não estão no Index._** 141 | 142 | Existem diversas outras funcionalidades para o comando **_git checkout_**, um bem legal é poder realizar o checkout de um arquivo a partir de um determinado id de commit gerado pelo próprio Github: 143 | 144 | ``` 145 | git checkout id_do_commit nome_do_arquivo 146 | ``` 147 | 148 | Mais informações a respeito deste comando, [clique aqui.](https://www.atlassian.com/git/tutorials/undoing-changes) 149 | 150 | ### 2. Atualizando seu repositório local 151 | 152 | Quando trabalhamos em um time, normalmente cada participante trabalha em sua própria branch e depois há a junção do que foi desenvolvido por cada um para a branch principal. No entanto as vezes precisamos atualizar a nossa branch com aquilo que já foi desenvolvido por alguém, ou até mesmo porque já houveram mudanças na branch principal do projeto. Para isto precisamos 'puxar' estas modificações para dentro do nosso repositório local, isto se faz através do comando: 153 | 154 | ``` 155 | git pull 156 | ``` 157 | 158 | Legal, mas eu quero que as modificações do meu time estejam na minha branch antes de eu realizar o **push** para a **master**, é possível? Sim através do comando abaixo, podemos realizar a 'mesclagem' de branchs distintas: 159 | ``` 160 | git merge nome_da_branch_a_ser_mesclada 161 | ``` 162 | 163 | Tá, fiz isso mas o git tá reclamando que já alteraram o mesmo arquivo que eu modifiquei, e agora? Nesse caso temos que fazer o merge de forma manual pois o Git não consegue identificar qual é a modificação correta a ser enviada. Para sabermos quais arquivos estão com conflito, basta executarmos o comando **git status** e os que tiverem com problema de merge estarão listados com a tag **_unmerged_**. 164 | 165 | ```shell 166 | > git status 167 | github.md: needs merge 168 | # On branch master 169 | # Changes not staged for commit: 170 | # (use "git add ..." to update what will be committed) 171 | # (use "git checkout -- ..." to discard changes in working directory) 172 | # 173 | # unmerged: github.md 174 | # 175 | ``` 176 | 177 | **_Obs.: Um outro comando para visualizar as alterações não mergeadas é o comando git diff. Mais informações a respeito deste comando, [clique aqui.](https://veerasundar.com/blog/2011/06/git-tutorial-comparing-files-with-diff/)_** 178 | 179 | Após a resolução dos confitos, basta seguirmos o fluxo básico de **add**, **commit** e **push** explicados acima. 180 | 181 | ### 3. Descartando nossas modificações 182 | 183 | \- **_"Quer saber..O que eu fiz tá tudo errado, quero remover tudo o que eu fiz, desde o que eu commitei até o que eu ainda estou trabalhando no momento, tem jeito?!"_** :rage: 184 | 185 | \-Calma, que tudo tem um jeito :innocent: 186 | 187 | Primeiro passo, recuperar a versão mais recente do servidor remoto através do comando: 188 | 189 | ``` 190 | git fetch origin 191 | ``` 192 | 193 | Após isto podemos realizar o 'reset' do repositório como um todo ou apenas de um arquivo :) 194 | 195 | Repositório: 196 | ``` 197 | git reset --hard origin/master 198 | ``` 199 | 200 | Arquivo: 201 | ``` 202 | git reset HEAD github.txt 203 | ``` 204 | 205 | --- 206 | ## Considerações finais e referências 207 | 208 | Como podemos observar o Git é o controlador de versão mais utilizado e mais poderoso do momento, listamos acima apenas alguns dos comandos principais porém existem uma gama de outros comandos que nos ajudam no dia-a-dia. Deixarei abaixo alguns links contendo materias e outros conteúdos além dos listados acima, porém sempre que possível irei atualizando pra deixar este tutorial ainda mais completo. Espero que tenha ficado claro e é óbvio que sugestões serão sempre bem-vindas :) 209 | 210 | ### Referências: 211 | 212 | * https://git-scm.com/book/pt-br/v1/ 213 | 214 | * http://rogerdudler.github.io/git-guide/index.pt_BR.html 215 | 216 | * http://www.keeptesting.com.br/2014/09/30/dicas-de-git-para-testers/ 217 | 218 | * https://backlog.com/git-tutorial/en/intro/intro1_4.html 219 | 220 | * https://tableless.com.br/tudo-que-voce-queria-saber-sobre-git-e-github-mas-tinha-vergonha-de-perguntar/ 221 | 222 | * https://veerasundar.com/blog/2011/06/git-tutorial-comparing-files-with-diff/ 223 | -------------------------------------------------------------------------------- /tests/Bundler/01-introducao_bundler.md: -------------------------------------------------------------------------------- 1 | # Bundler 2 | 3 | O Bundler fornece um ambiente consistente para projetos Ruby, rastreando e instalando gemas e versões exatas que são necessárias. 4 | 5 | Bundler é uma saída do inferno de dependência e garante que as gemas que você precisa estão presentes no desenvolvimento, estadiamento e produção. Começar o trabalho em um projeto é tão simples quanto bundle install. 6 | 7 | ## Começando 8 | 9 | Começar com bundler é fácil! Abra uma janela do terminal e execute este comando: 10 | 11 | ```ruby 12 | $ gem install bundler 13 | ``` 14 | 15 | Especifique suas dependências em um Gemfile na raiz do seu projeto: 16 | 17 | ```ruby 18 | source 'https://rubygems.org' 19 | gem 'nokogiri' 20 | gem 'rack', '~> 2.0.1' 21 | gem 'rspec' 22 | ``` 23 | 24 | ## Intalando as gems com bundle 25 | Instale todas as gemas necessárias das suas fontes especificadas: 26 | 27 | ```ruby 28 | $ bundle install 29 | ``` 30 | $ git add Gemfile Gemfile.lock 31 | 32 | 33 | 1. [Comandos Bundler](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/comandos_bundler.md); -------------------------------------------------------------------------------- /tests/Bundler/02-opcoes_extras_bundle_install.md: -------------------------------------------------------------------------------- 1 | # Opções do bunlde install 2 | 3 | Para aplicar qualquer um --binstubs, --deployment, --path, ou --withoutcada vez que bundle installé executado, usar bundle config(ver pacote-config (1) ). 4 | 5 | ```ruby 6 | --binstubs[=] 7 | ``` 8 | 9 | Cria um diretório (padrão para ~/bin) e coloca todos os executáveis ​​a partir da gema lá. Esses executáveis ​​são executados no contexto do Bundler. Se usado, você pode adicionar este diretório à PATHvariável do seu ambiente . Por exemplo, se a railsgema vem com um railsexecutável, esta bandeira criará um bin/railsexecutável que garanta que todas as dependências referidas serão resolvidas usando as gemas agrupadas. 10 | 11 | ```ruby 12 | --clean 13 | ``` 14 | 15 | Ao finalizar a instalação, o Bundler irá remover todas as gemas que não estejam presentes no Gemfile atual (5) . Não se preocupe, gemas atualmente em uso não serão removidas. 16 | 17 | ```ruby 18 | --deployment 19 | ``` 20 | 21 | No modo de implantação , o Bundler irá "lançar" o pacote para produção ou uso de CI. Verifique com atenção se deseja que esta opção seja ativada em seu ambiente de desenvolvimento. 22 | 23 | ```ruby 24 | --force 25 | ``` 26 | 27 | Força baixar todas as gemas, mesmo que as versões necessárias já estejam disponíveis localmente. 28 | 29 | ```ruby 30 | --frozen 31 | ``` 32 | 33 | Não permita que o Gemfile.lock seja atualizado após essa instalação. Sai não-zero se houver mudanças no Gemfile.lock. 34 | 35 | ```ruby 36 | --full-index 37 | ``` 38 | 39 | O Bundler não chamará o ponto final da API da Rubygems (padrão), mas baixará e armazena em cache um arquivo de índice (atualmente grande) de todas as gemas. O desempenho pode ser melhorado para pacotes grandes que raramente mudam ao ativar esta opção. 40 | 41 | ```ruby 42 | --gemfile= 43 | ``` 44 | 45 | A localização do Gemfile (5) que o Bundler deve usar. Este padrão é um Gemfile (5) no diretório de trabalho atual. Em geral, o Bundler assumirá que a localização do Gemfile (5) também é a raiz do projeto e tentará encontrar Gemfile.locke em vendor/cacherelação a esse local. 46 | 47 | ```ruby 48 | --jobs=[], -j[] 49 | ``` 50 | O número máximo de trabalhos paralelos de download e instalação. O padrão é 1. 51 | 52 | ```ruby 53 | --local 54 | ``` 55 | 56 | Não tente se conectar rubygems.org. Em vez disso, o Bundler usará as gemas já presentes no cache de Rubygems ou dentro vendor/cache. Tenha em atenção que, se existir uma gem específica específica da plataforma, rubygems.orgela não será encontrada. 57 | 58 | ```ruby 59 | --no-cache 60 | ``` 61 | 62 | Não atualize o cache vendor/cachecom as gemas recém-juntas. Isso não remove gemas no cache, mas mantém as gemas recém-agrupadas a serem armazenadas em cache durante a instalação. 63 | 64 | ```ruby 65 | --no-prune 66 | ``` 67 | 68 | Não remova gemas obsoletas do cache quando a instalação terminar. 69 | 70 | ```ruby 71 | --path= 72 | ``` 73 | 74 | A localização para instalar as gemas especificadas. Este padrão é a configuração do Rubygems. Bundler compartilha esta localização com Rubygems, gem install ...também terá gem instalado lá. Portanto, gemas instaladas sem uma --path ...configuração aparecerão ligando gem list. Consequentemente, as gemas instaladas em outros locais não serão listadas. 75 | 76 | ```ruby 77 | --quiet 78 | ``` 79 | 80 | Não imprima informações de progresso na saída padrão. Em vez disso, o Bundler irá sair usando um código de status ( $?). 81 | 82 | ```ruby 83 | --retry=[] 84 | ``` 85 | 86 | Tente novamente as solicitações de rede ou git com falha para o número de vezes. 87 | 88 | ```ruby 89 | --shebang= 90 | ``` 91 | 92 | Usa o executável ruby ​​especificado (geralmente ruby) para executar os scripts criados com --binstubs. Além disso, se você usar --binstubsjunto com --shebang jrubyesses executáveis ​​será alterado para executar em jruby vez disso. 93 | 94 | ```ruby 95 | --standalone[=] 96 | ``` 97 | 98 | Faz um pacote que pode funcionar sem depender de Rubygems ou Bundler no tempo de execução. É necessário especificar uma lista separada de espaços para instalar. O Bundler cria um diretório chamado bundlee instala o pacote lá. Ele também gera um bundle/bundler/setup.rbarquivo para substituir a própria instalação do Bundler da maneira requerida. Usar esta opção implícitamente define path, que é uma [opção lembrada] [OPÇÕES RECEBIDAS]. 99 | 100 | ```ruby 101 | --system 102 | ``` 103 | 104 | Instala as gemas especificadas no pacote para a localização do Rubygems do sistema. Isso substitui qualquer configuração anterior de --path. 105 | 106 | ```ruby 107 | --trust-policy=[] 108 | ``` 109 | 110 | Aplicar a política de segurança Rubygems política , onde a política é um dos HighSecurity, MediumSecurity, LowSecurity, AlmostNoSecurity, ou NoSecurity. Para obter mais detalhes, consulte a documentação de assinatura da Rubygems, ligada abaixo, em VER TAMBÉM . 111 | 112 | ```ruby 113 | --with= 114 | ``` 115 | 116 | Uma lista separada por espaço de grupos referentes a gemas para instalar. Se for dado um grupo opcional, ele está instalado. Se for dado um grupo que esteja na lista lembrada de grupos atribuídos a - sem, ele é removido dessa lista. 117 | 118 | ```ruby 119 | --without= 120 | ``` 121 | 122 | Uma lista de grupos separados por espaços referentes a gemas para ignorar durante a instalação. Se for dado um grupo que esteja na lista lembrada de grupos atribuídos a - com, ele será removido dessa lista. 123 | -------------------------------------------------------------------------------- /tests/Bundler/03-opcoes_extras_bundle_update.md: -------------------------------------------------------------------------------- 1 | # Opções para bundle update 2 | 3 | ```ruby 4 | --group=, -g=[] 5 | ``` 6 | 7 | Apenas atualize as gemas no grupo especificado. Por exemplo, você pode atualizar todas as gemas no grupo de desenvolvimento com bundle update --group development. Você também pode ligar bundle update rails --group testpara atualizar a jóia dos trilhos e todas as gemas no grupo de teste, por exemplo. 8 | 9 | ```ruby 10 | --source= 11 | ``` 12 | 13 | O nome de uma :gitou :pathfonte usada no Gemfile (5) . Por exemplo, com uma :gitfonte de http://github.com/rails/rails.git, você ligariabundle update --source rails 14 | 15 | ```ruby 16 | --local 17 | ``` 18 | 19 | Não tente obter gemas remotamente e use o cache de gema em vez disso. 20 | 21 | ```ruby 22 | --ruby 23 | ``` 24 | 25 | Atualize a versão bloqueada do Ruby para a versão atual do Ruby. 26 | 27 | ```ruby 28 | --bundler 29 | ``` 30 | 31 | Atualize a versão bloqueada do bundler para a versão do bundler invocado. 32 | 33 | ```ruby 34 | --full-index 35 | ``` 36 | 37 | Volte a usar o índice de arquivo único de todas as gemas. 38 | 39 | ```ruby 40 | --jobs=[], -j[] 41 | ``` 42 | 43 | Especifique o número de trabalhos a serem executados em paralelo. O padrão é 1. 44 | 45 | ```ruby 46 | --retry=[] 47 | ``` 48 | 49 | Tente novamente as solicitações de rede ou git com falha para o número de vezes. 50 | 51 | ```ruby 52 | --quiet 53 | ``` 54 | 55 | Apenas avisos e erros de saída. 56 | 57 | ```ruby 58 | --force 59 | ``` 60 | 61 | Force baixar todas as gemas. 62 | 63 | ```ruby 64 | --patch 65 | ``` 66 | 67 | Prefira atualizar apenas para a próxima versão do patch. 68 | 69 | ```ruby 70 | --minor 71 | ``` 72 | 73 | Prefere atualizar apenas para a próxima versão secundária. 74 | 75 | ```ruby 76 | --major 77 | ``` 78 | 79 | Prefira atualizar para a próxima versão principal (padrão). 80 | 81 | ```ruby 82 | --strict 83 | ``` 84 | 85 | Não permita que nenhuma jóia seja atualizada mais recente --patch| --minor| --major. 86 | 87 | ```ruby 88 | --conservative 89 | ``` 90 | 91 | Use o comportamento da atualização conservadora da instalação do pacote e não permita que as dependências compartilhadas sejam atualizadas. 92 | -------------------------------------------------------------------------------- /tests/Bundler/04-comandos_extras_bundle_config.md: -------------------------------------------------------------------------------- 1 | # Opção do bundle config 2 | 3 | As opções que podem ser configuradas são: 4 | 5 | ```ruby 6 | bin 7 | ``` 8 | 9 | Cria um diretório (padrão para ~/bin) e coloca todos os executáveis ​​a partir da gema lá. Esses executáveis ​​são executados no contexto do Bundler. Se usado, você pode adicionar este diretório à PATHvariável do seu ambiente . Por exemplo, se a railsgema vem com um railsexecutável, esta bandeira criará um bin/railsexecutável que garanta que todas as dependências referidas serão resolvidas usando as gemas agrupadas. 10 | 11 | ```ruby 12 | deployment 13 | ``` 14 | 15 | No modo de implantação, o Bundler irá "lançar" o pacote para productionuso. Verifique com atenção se você deseja que esta opção seja ativada developmentou testambientes. 16 | 17 | ```ruby 18 | path 19 | ``` 20 | A localização para instalar as gemas especificadas. Este padrão é a configuração do Rubygems. Bundler compartilha esta localização com Rubygems, gem install ...também terá gem instalado lá. Portanto, gemas instaladas sem uma --path ...configuração aparecerão ligando gem list. Consequentemente, as gemas instaladas em outros locais não serão listadas. 21 | 22 | ```ruby 23 | without 24 | ``` 25 | 26 | Uma lista de grupos separados por espaços referentes a gemas para ignorar durante a instalação. 27 | 28 | ```ruby 29 | with 30 | ``` 31 | 32 | Uma lista separada por espaço de grupos referentes a gemas para incluir durante a instalação. 33 | -------------------------------------------------------------------------------- /tests/Bundler/comandos_bundler.md: -------------------------------------------------------------------------------- 1 | # COMANDOS BUNDLER 2 | 3 | BUNDLE INSTALL: 4 | 5 | Instale as dependências especificadas no seu Gemfile 6 | 7 | ```ruby 8 | $ bundle install 9 | ``` 10 | 11 | EXISTE MAIS UMAS OPÇÕES COMPLEMENTARES PARA O BUNDLE INSTALL 12 | 1. [Opções extras do bundle install](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/02-opcoes_extras_bundle_install.md); 13 | 14 | BUNDLE UPDATE: 15 | Atualize suas gemas para as últimas versões disponíveis 16 | 17 | ```ruby 18 | $ bundle update 19 | ``` 20 | EXISTE MAIS UMAS OPÇÕES COMPLEMENTARES PARA O BUNDLE UPDATE 21 | 22 | 2. [Opções extras do bundle update](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/03-opcoes_extras_bundle_update.md); 23 | 24 | BUNDLE PACKAGE: 25 | 26 | bundle-package- Coloque os .gem arquivos necessários em seu aplicativo 27 | 28 | ```ruby 29 | $ bundle package 30 | ``` 31 | 32 | BUNDLE EXEC: 33 | 34 | Este comando executa o comando, fazendo com que todas as gemas especificadas no seu gem file 35 | 36 | bundle-exec- Execute um comando no contexto do pacote 37 | 38 | ```ruby 39 | $ bundle exec 40 | ``` 41 | 42 | BUNDLE CONFIG: 43 | 44 | Este comando permite que você interaja com o sistema de configuração do bundler. O Bundler recupera sua configuração do aplicativo local ( app/.bundle/config), das variáveis ​​de ambiente e do diretório inicial do usuário ( ~/.bundle/config), nessa ordem de prioridade. 45 | 46 | bundle-config- Definir opções de configuração do pacote 47 | 48 | ```ruby 49 | $ bundle config [name [value]] 50 | ``` 51 | EXISTE MAIS UMAS OPÇÕES COMPLEMENTARES PARA O BUNDLE CONFIG 52 | 53 | 3. [Opções extras do bundle config](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/04-comandos_extras_bundle_config.md); 54 | 55 | MAIS EM BREVE... 56 | -------------------------------------------------------------------------------- /tests/Calabash/comandos_calabash.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Capybara/01-introducao.md: -------------------------------------------------------------------------------- 1 | # Capybara 2 | 3 | ## Introdução 4 | 5 | Capybara é um framework de automação de testes em aplicações web, open-source, e escrito em Ruby. É utilizado para testar as aplicações simulando as ações que os usuários reais executariam na aplicação. Para utilizar o Capybara é necessário ter instalado o [Ruby](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/configuracao_ruby.md); 6 | 7 | **Vamos para o próximo post** [Instalando os drivers](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/02-instalando_drivers.md); -------------------------------------------------------------------------------- /tests/Capybara/02-instalando_drivers.md: -------------------------------------------------------------------------------- 1 | 2 | # Instalando os Drivers 3 | 4 | ## Chromedriver 5 | 6 | O ChromeDriver é um servidor autônomo que implementa o protocolo de fio da WebDriver para o Chromium, que está disponível para o Chrome no Android e no Chrome na área de trabalho (Mac, Linux, Windows e ChromeOS) 7 | > Download: https://bit.ly/2e6e5sz 8 | 9 | ## GeckoDriver 10 | 11 | Gecko Driver é a conexão entre seus testes em Selenium e o programa Firefox. Clientes compatíveis para interagir com navegadores baseados em Gecko, ou seja, Mozilla Firefox para esta situação. 12 | > Download: https://bit.ly/2joYOJD 13 | 14 | ## PhantomJS 15 | 16 | PhantomJS é basicamente um browser sem interface gráfica baseado no WebKit (similar ao Safari e Google Chrome), onde você roda em background e manipula via API JavaScript. A vantagem de usar o PhantomJS é que ele é compátivel com qualquer sistema de poder ser instalado em qualquer máquina. 17 | > Download: https://bit.ly/2re71RE 18 | 19 | ## Instalando ChromeDriver, GeckoDriver e PhantomJS no Windows 20 | 21 | > Temos duas opções de instalação dos drivers 22 | 23 | **Instalação manual** 24 | 25 | 1. Baixe os respectivos drivers nos links de download logo acima. 26 | 2. Se necessário, extraia o arquivo .exe para alguma pasta do seu desktop. 27 | 3. Coloque os executáveis dentro da pasta **C:\Windows** e *voilà* 28 | 29 | **Instalação via NPM** 30 | 31 | 1. Baixe o NodeJs no site https://bit.ly/1LjG5AH e execute a instalação 32 | 2. Para verificar se a instalação foi um sucesso, abra o PowerShell ou CMDER e digite os seguintes comandos: 33 | `node -v` 34 | `npm -v` 35 | >Você deve receber de retorno as versões das ferramentas. 36 | 4. Com o PowerShell ou CMDER aberto, para instalar o GeckoDriver, o ChromeDriver e o PhantomJS, digite: 37 | > GeckoDriver 38 | `npm install -g geckodriver ` 39 | 40 | > ChromeDriver 41 | `npm install -g chromedriver` 42 | 43 | > PhantomJS 44 | `npm install -g phantomjs-prebuilt` 45 | 46 | 47 | ## Instalando ChromeDriver, GeckoDriver e PhamtomJS no Mac: 48 | 49 | A instalação no MacOS, assim como no Linux, é ainda mais fácil. 50 | 51 | 1. Abra o terminal e instale o HomeBrew com o comando: 52 | ```/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"``` 53 | 54 | 2. Para verificar se o HomeBrew foi instalado corretamente, digite **which brew**. Você deverá ver algo como: 55 | >**/usr/local/bin/brew** 56 | 57 | 3. Para instalar o GeckoDriver, o ChromeDriver e o PhantomJs, digite: 58 | > GeckoDriver 59 | `brew install geckodriver ` 60 | 61 | > ChromeDriver 62 | `brew install chromedriver` 63 | 64 | > PhantomJS 65 | `brew install phantomjs` 66 | 67 | ## Instalando ChromeDriver, GeckoDriver e PhantomJS no Linux: 68 | 69 | Para instalar os drivers no Linux, podemos usar o mesmo método do NPM. Apenas uma observação que o Linux possui algumas particuladores na hora de instalar o Node. Basta seguir este guia https://bit.ly/2HD54sW que vai dar tudo certo! 70 | 1. Com o Terminal aberto, para instalar o GeckoDriver, o ChromeDriver e o PhantomJS, digite: 71 | > GeckoDriver 72 | `npm install -g geckodriver ` 73 | 74 | > ChromeDriver 75 | `npm install -g chromedriver` 76 | 77 | > PhantomJS 78 | `npm install -g phantomjs-prebuilt` 79 | 80 | **Vamos para o próximo post** [Configuração](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/03-configurando_projeto.md); 81 | 82 | -------------------------------------------------------------------------------- /tests/Capybara/03-configurando_projeto.md: -------------------------------------------------------------------------------- 1 | # Configuração 2 | 3 | Depois de ter instalado os [Drivers](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/02-instalando_drivers.md) 4 | 5 | Agora vamos configurar nosso projeto ruby com capybara 6 | 7 | Primeiro vc precisa ter instalado o [Bundler](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/01-introducao_bundler.md) 8 | 9 | # Configuração 10 | 11 | Agora vamos configurar nosso projeto ruby com capybara 12 | 13 | Primeiro vc precisa ter instalado o [Bundler](https://github.com/brunobatista25/best_archer/blob/master/tests/Bundler/01-introducao_bundler.md) 14 | 15 | 16 | Agora crie um arquivo chamado Gemfile sem nenhuma extensão, agora dentro do arquivo coloque os seguintes conteúdos: 17 | 18 | ```ruby 19 | source 'http://rubygems.org' 20 | 21 | gem 'capybara' 22 | gem 'selenium-webdriver' 23 | ``` 24 | 25 | Essa são as gems minímas para se configurar o projeto com capybara 26 | 27 | Capybara será o framework de desenvolvimento. 28 | 29 | Selenium Webdriver será o Driver base e abrir o Chrome para automação. 30 | 31 | Agora rode o comando 32 | 33 | ```ruby 34 | bundle install 35 | ``` 36 | 37 | Todas a gems serão instaladas e um outro arquivo sera criado automaticamente Gemfile.lock 38 | 39 | **Configurando o ENV.RB** 40 | 41 | Dentro desse arquivo temos que especificar as gems que serão utilizadas 42 | 43 | ```ruby 44 | require 'capybara' 45 | require 'selenium-webdriver' 46 | ``` 47 | 48 | **Agora iremos adicionar umas configurações do capybara neste mesmo arquivo:** 49 | 50 | ```ruby 51 | require 'capybara' 52 | require 'selenium-webdriver' 53 | 54 | Capybara.configure do |config| 55 | config.default_driver = :selenium 56 | config.app_host = "https://www.google.com/" 57 | config.default_max_wait_time = 30 58 | end 59 | ``` 60 | 61 | ```ruby 62 | #Estou definindo que o driver que vou utilizar e o selenium webdriver. 63 | Capybara.default_driver = :selenium 64 | ``` 65 | 66 | ```ruby 67 | #Esse comando e a configuraçaão para qual tempo minímo para esperar um elemento na tela 68 | Capybara.default_max_wait_time = 30 69 | ``` 70 | 71 | ```ruby 72 | #Aqui configuro qual url so site que estou usando 73 | Capybara.app_host 74 | ``` 75 | 76 | ## Configurar qual navegador usar para automação 77 | 78 | Dentro deste mesmo arquivo iremos colocar a configuração de qual navegador iremos usar 79 | 80 | ## Chrome 81 | 82 | 83 | Para usar o chrome basta usar a seguinte configuração 84 | 85 | ```ruby 86 | require 'capybara' 87 | require 'selenium-webdriver' 88 | 89 | Capybara.configure do |config| 90 | config.default_driver = :selenium_chrome 91 | config.app_host = "https://www.google.com/" 92 | config.default_max_wait_time = 30 93 | end 94 | ``` 95 | 96 | ou 97 | 98 | ```ruby 99 | require 'capybara' 100 | require 'selenium-webdriver' 101 | 102 | Capybara.register_driver :selenium do |app| 103 | Capybara::Selenium::Driver.new(app, browser: :chrome) 104 | end 105 | 106 | Capybara.configure do |config| 107 | config.default_driver = :selenium 108 | config.app_host = "https://www.google.com/" 109 | config.default_max_wait_time = 30 110 | end 111 | 112 | ``` 113 | 114 | ## Firefox 115 | 116 | Para usar o firefox basta usar a seguinte configuração 117 | 118 | ```ruby 119 | require 'capybara' 120 | require 'selenium-webdriver' 121 | 122 | Capybara.configure do |config| 123 | config.default_driver = :selenium 124 | config.app_host = "https://www.google.com/" 125 | config.default_max_wait_time = 30 126 | end 127 | ``` 128 | 129 | ```ruby 130 | require 'capybara' 131 | require 'selenium-webdriver' 132 | 133 | Capybara.register_driver :selenium do |app| 134 | Capybara::Selenium::Driver.new(app, browser: :firefox) 135 | end 136 | 137 | Capybara.configure do |config| 138 | config.default_driver = :selenium 139 | config.app_host = "https://www.google.com/" 140 | config.default_max_wait_time = 30 141 | end 142 | ``` 143 | 144 | **Vamos para o próximo post** [Acessando Url](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/04-acessando_url.md); 145 | -------------------------------------------------------------------------------- /tests/Capybara/04-acessando_url.md: -------------------------------------------------------------------------------- 1 | # Navegação 2 | 3 | ## Visit 4 | Você pode usar o método de "visit" para navegar para outras páginas: 5 | O método de visit só aceita um único parâmetro, o método de solicitação é sempre GET. 6 | 7 | ``` 8 | visit('https://www.site.com.br') 9 | ``` 10 | 11 | ## have_current_path 12 | 13 | Você pode obter o caminho atual da sessão de navegação e testá-lo usando o have_current_path correspondente: 14 | 15 | ```ruby 16 | expect(page).to have_current_path('https://www.site.com.br', url: true) 17 | ``` 18 | 19 | ## current_url 20 | URL totalmente qualificado da página atual. 21 | 22 | ```ruby 23 | url = page.current_url 24 | puts url 25 | ``` 26 | 27 | **Vamos para o próximo post** [Buscando elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/05-buscando_elementos.md); 28 | -------------------------------------------------------------------------------- /tests/Capybara/05-buscando_elementos.md: -------------------------------------------------------------------------------- 1 | # Buscando Elementos 2 | 3 | Você também pode encontrar elementos específicos, a fim de manipulá-los: 4 | 5 | ## all 6 | 7 | Encontre todos os elementos na página que correspondem ao seletor e opções fornecidos. 8 | 9 | ```ruby 10 | page.all(:css, 'elemento') 11 | ``` 12 | 13 | ## ancestor 14 | 15 | Encontre um elemento com base nos argumentos fornecidos que também é um ancestral do elemento chamado. 16 | 17 | ```ruby 18 | element.ancestor('#foo').find('.bar') 19 | ``` 20 | 21 | ## find 22 | 23 | Encontre um elemento com base nos argumentos fornecidos. 24 | 25 | ```ruby 26 | find('elemento') 27 | ``` 28 | 29 | ## find_button 30 | 31 | Encontre um botão na página. 32 | 33 | ```ruby 34 | find_button('elemento_do_botao') 35 | ``` 36 | 37 | ## find_by_id 38 | 39 | Encontre um elemento na página, dado seu id. 40 | 41 | ```ruby 42 | find_by_id('id_do_elemento') 43 | ``` 44 | 45 | ## find_field 46 | 47 | Encontre um campo de formulário na página. 48 | 49 | ```ruby 50 | find_field('elemento') 51 | ``` 52 | 53 | ## find_link 54 | 55 | Encontre um link na página. 56 | 57 | ```ruby 58 | find_link('link_do_elemento') 59 | ``` 60 | 61 | ## first 62 | 63 | Encontre o primeiro elemento na página que corresponda ao seletor e opções fornecidos. 64 | 65 | ```ruby 66 | first('elemento') 67 | ``` 68 | 69 | ## sibling 70 | 71 | Encontre um elemento baseado nos argumentos dados que também é um irmão do elemento chamado. 72 | 73 | ```ruby 74 | element.sibling('elemento') 75 | ``` 76 | 77 | ---------------------------------------------------------------------------------------- 78 | ## Pegando valores dos elementos 79 | 80 | ## PEGAR VALOR 81 | 82 | # [] 83 | Recupere o atributo fornecido. 84 | 85 | ```ruby 86 | element = find('elemento') 87 | element[:title] 88 | ``` 89 | 90 | #tag_name ⇒ String 91 | O nome da tag do elemento. 92 | 93 | ```ruby 94 | find.('elemento').tag_name 95 | ``` 96 | 97 | #text(_type = nil) ⇒ String 98 | O texto do elemento. 99 | 100 | ```ruby 101 | find.('elemento').text 102 | ``` 103 | 104 | #title ⇒ String 105 | O título do documento. 106 | 107 | ```ruby 108 | find.('elemento').title 109 | ``` 110 | 111 | #value ⇒ String 112 | O valor do elemento de formulário. 113 | 114 | ```ruby 115 | find.('elemento').value 116 | ``` 117 | ----------------------------------------------------------------------------- 118 | 119 | ## Opçōes para auxiliares para buscas. 120 | 121 | ** Essas opçōes não são para todos o comandos não, sugiro ir na domcumentação e ver qual comando comando usa as opcōes nesse [Link](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders) 122 | 123 | 124 | **:all** - encontra um campo ativado ou desativado 125 | 126 | **alt** - Corresponder links com um elemento img contido, cujo alt corresponde 127 | 128 | **between** - O número de correspondências encontradas deve estar dentro do intervalo determinado 129 | 130 | **checked** - Corresponder campo verificado? 131 | 132 | **class** - Corresponder links que correspondam à (s) classe (s) fornecida (s) 133 | 134 | **count** - Número exato de correspondências que se espera encontrar 135 | 136 | **disabled** - padrão: false - Corresponder campo desativado? 137 | 138 | **exact** - Controlar se as expressões `is` no determinado XPath correspondem exatamente ou parcialmente 139 | 140 | **exact_text** - Quando String, o texto contido no elemento deve corresponder exatamente, quando o Boolean controla se a opção: text deve corresponder exatamente 141 | 142 | **false** - só encontra um campo ativado 143 | 144 | **:hidden** - só encontra elementos invisíveis. 145 | 146 | **href** - Valor para combinar com os links href, se nil encontrar espaços reservados para links ( elementos sem atributo href) 147 | 148 | **id** - Corresponder links com o ID fornecido 149 | 150 | **match** - A estratégia de correspondência a ser usada. 151 | 152 | **maximum** - Número máximo de correspondências que se espera encontrar 153 | 154 | **minimum** - Número mínimo de correspondências que se espera encontrar 155 | 156 | **multiple** - Corresponder campos que podem ter vários valores? 157 | 158 | **name** - Corresponder campos que correspondem ao atributo name 159 | 160 | **placeholder** - Corresponder campos que correspondam ao atributo de espaço reservado 161 | 162 | **readonly** - Corresponder campo readonly? 163 | 164 | **text** - Apenas encontre elementos que contenham este texto ou correspondam a este regexp 165 | 166 | **title** - Corresponder links com o título fornecido 167 | 168 | **true** - só encontra um campo desativado 169 | 170 | **type** - Tipo de campo para combinar 171 | 172 | **unchecked** - Corresponder campo desmarcado? 173 | 174 | **value** - Corresponder botões com o valor fornecido 175 | 176 | **visible** - Apenas encontre elementos com a visibilidade especificada: 177 | 178 | **:visible** - o mesmo que true; só encontra elementos visíveis. 179 | 180 | **wait** - Tempo máximo para aguardar a exibição do elemento correspondente. 181 | 182 | **with** - Valor do campo para combinar 183 | 184 | **Vamos para o próximo post** [Realizando açōes](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/06-realizando_acoes.md); -------------------------------------------------------------------------------- /tests/Capybara/06-realizando_acoes.md: -------------------------------------------------------------------------------- 1 | ## Realizando Açōes 2 | 3 | ------------------------------------------------------------------------------- 4 | 5 | ## Preenchendo campos 6 | 7 | ## fill_in 8 | 9 | Localize um campo de texto ou área de texto e preencha-o com o texto fornecido O campo pode ser encontrado através do seu nome, identificação ou texto da etiqueta. 10 | 11 | ```ruby 12 | fill_in 'Name', with: 'Bob' 13 | ``` 14 | 15 | ## .send_keys 16 | 17 | Enviar pressionamentos de tecla para o elemento. 18 | 19 | ```ruby 20 | find('elemento').send_keys('bruno') 21 | ``` 22 | 23 | ## .set 24 | 25 | Defina o valor do elemento de formulário para o valor fornecido. 26 | 27 | ```ruby 28 | find('elemento').set('bruno') 29 | ``` 30 | 31 | ------------------------------------------------------------------------------- 32 | ## Clicando em elementos 33 | 34 | ## click_button 35 | 36 | Encontra um botão na página e clica nele. 37 | 38 | ```ruby 39 | click_button('botao') 40 | ``` 41 | 42 | ## click_link 43 | 44 | Encontra um link por id, texto ou título e clica nele. 45 | 46 | ```ruby 47 | click_link('link') 48 | ``` 49 | 50 | ## click_link_or_button 51 | 52 | Encontra um botão ou link e clica nele. 53 | 54 | ```ruby 55 | click_link_or_button('linkoubotao') 56 | ``` 57 | 58 | ## .double_click 59 | 60 | Clique duas vezes no elemento. 61 | 62 | ```ruby 63 | find('botao').double_click 64 | ``` 65 | 66 | ## .click 67 | 68 | Clique no elemento. 69 | 70 | ```ruby 71 | find('botao').click 72 | ``` 73 | 74 | ## .right_click 75 | 76 | Clique com o botão direito no elemento. 77 | 78 | ```ruby 79 | find('botao').right_click 80 | ``` 81 | 82 | ------------------------------------------------------------------------------- 83 | ## RadioBox e CheckBox 84 | 85 | ## check 86 | 87 | Encontre uma caixa de seleção e marque-a como marcado. 88 | 89 | ```ruby 90 | page.check('German') 91 | ``` 92 | 93 | ## uncheck 94 | 95 | Encontre uma caixa de seleção e marque a caixa de seleção. 96 | 97 | ```ruby 98 | uncheck('German') 99 | 100 | ``` 101 | 102 | ## choose 103 | 104 | Encontre um botão de opção e marque-o como marcado. 105 | 106 | ```ruby 107 | page.choose('Male') 108 | ``` 109 | 110 | ------------------------------------------------------------------------------- 111 | ## Upload de Arquivo 112 | 113 | ## attach_file 114 | 115 | Encontre um campo de arquivo na página e anexe um arquivo ao seu caminho. 116 | 117 | ```ruby 118 | page.attach_file(locator, '/path/to/file.png') 119 | ``` 120 | 121 | ------------------------------------------------------------------------------- 122 | 123 | ## Drag and Drop 124 | 125 | ## .drag_to 126 | 127 | Move um elemento para outra posição 128 | 129 | ```ruby 130 | @primeiro_elemento = find('#winston') 131 | @segundo_elemento = find('#dropzone') 132 | @primeiro_elemento.drag_to(@segundo_elemento) 133 | ``` 134 | 135 | ------------------------------------------------------------------------------- 136 | 137 | ## Mousehover 138 | 139 | ## .hover 140 | 141 | Passe o mouse sobre o elemento. 142 | 143 | ```ruby 144 | find('elemento').hover 145 | 146 | find('.activator').hover.click 147 | ``` 148 | 149 | ------------------------------------------------------------------------------- 150 | 151 | ## Combobox 152 | 153 | ## select 154 | 155 | Se a opção `:from` estiver presente, o `select` encontra uma caixa de seleção na página e seleciona uma opção particular dela. Caso contrário, ele encontrará uma opção dentro do escopo atual e a selecionará. Se a caixa de seleção for uma seleção múltipla, selecione pode ser chamado várias vezes para selecionar mais de uma opção. A caixa de seleção pode ser encontrada pelo nome, identificação ou texto da etiqueta. A opção pode ser encontrada pelo seu texto. 156 | 157 | ```ruby 158 | select 'March', from: 'Month' 159 | ``` 160 | 161 | ## unselect 162 | 163 | Encontre uma caixa de seleção na página e desmarque uma opção específica dela. 164 | 165 | ```ruby 166 | unselect 'March', from: 'Month' 167 | ``` 168 | 169 | ## .select_option 170 | 171 | Selecione este nó se for um elemento de opção dentro de uma tag de seleção. 172 | 173 | ```ruby 174 | find('opcao').select_option 175 | ``` 176 | 177 | ## .unselect_option 178 | 179 | Desmarque este nó se for um elemento de opção dentro de uma tag de seleção múltipla. 180 | 181 | ```ruby 182 | find('opcao').unselect_option 183 | ``` 184 | 185 | ------------------------------------------------------------------------------- 186 | ## limpar campos 187 | 188 | #native 189 | 190 | ```ruby 191 | find('element').native.clear 192 | ``` 193 | 194 | ------------------------------------------------------------------------------ 195 | ## Opçōes para auxiliares para açōes. 196 | 197 | **Essas opçōes não são para todos o comandos não, sugiro ir na domcumentação e ver qual comando comando usa as opcōes nesse** [Link](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions) 198 | 199 | **:allow_label_click** - Tenta clicar no rótulo para alternar o estado se o elemento não estiver visível. 200 | 201 | **:class** - Campos de correspondência que correspondem à (s) classe (s) fornecida (s) 202 | 203 | **:class** - Corresponder campos que correspondam à (s) classe (s) fornecida (s) 204 | make_visible (true, Hash) - Um Hash de estilos CSS para alterar antes de tentar anexar o arquivo, se `true` {opacity: 1, display: 'block', visibilidade: 'visible'} é usado (pode não ser suportado por todos os drivers) 205 | *exact* - Corresponda o nome / conteúdo exato da etiqueta ou aceite uma correspondência parcial. 206 | 207 | **:currently_with** — A propriedade de valor atual do campo para preencher 208 | 209 | **:fill_options** — Opções específicas do driver sobre como preencher campos 210 | 211 | **:from** — O id, nome ou rótulo da caixa de seleção 212 | 213 | **id** - Corresponder campos que correspondem ao atributo id 214 | 215 | **match** - A estratégia de correspondência a ser usada (:one,:first,:prefer_exact,:smart). 216 | 217 | **multiple** - Campo de correspondência que permite a seleção de vários arquivos. 218 | 219 | **name** - Corresponder campos que correspondem ao atributo name 220 | 221 | **:option** (String) — Valor da caixa de seleção para selecionar 222 | 223 | **:option** — Valor do radio_button para escolher 224 | 225 | **:placeholder** — Corresponder campos que correspondam ao atributo de espaço reservado 226 | 227 | **wait** - Tempo máximo para aguardar a exibição do elemento correspondente. 228 | 229 | **:with** — O valor a preencher - obrigatório 230 | 231 | **Vamos para o próximo post** [Validando elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/07-validando_elementos.md); 232 | 233 | -------------------------------------------------------------------------------- 234 | -------------------------------------------------------------------------------- /tests/Capybara/07-validando_elementos.md: -------------------------------------------------------------------------------- 1 | ## Matchers 2 | 3 | ------------------------------------------------------------------------------ 4 | ## verificando elementos 5 | 6 | ## checked 7 | 8 | Se o elemento está ou não marcado. 9 | 10 | ```ruby 11 | find('name').checked 12 | ``` 13 | 14 | ## disabled? 15 | 16 | Se o elemento está ou não desativado. 17 | 18 | ```ruby 19 | find('name').disabled? 20 | ``` 21 | 22 | ## selected? 23 | 24 | Se o elemento está selecionado ou não. 25 | 26 | ```ruby 27 | find('name').selected? 28 | ``` 29 | 30 | ## visible? 31 | 32 | Se o elemento é visível ou não. 33 | 34 | ```ruby 35 | find('name').visible? 36 | ``` 37 | 38 | ## multiple? 39 | 40 | Se o elemento suporta ou não vários resultados. 41 | 42 | ```ruby 43 | find('name').multiple? 44 | ``` 45 | 46 | ## readonly? 47 | 48 | Se o elemento é ou não somente leitura. 49 | 50 | ```ruby 51 | find('name').readonly? 52 | ``` 53 | 54 | ------------------------------------------------------------------------------ 55 | 56 | ## Asserts 57 | 58 | ## assert_all_of_selectors 59 | 60 | Afirma que todos os seletores fornecidos estão presentes na página ou nos descendentes do nó atual. 61 | 62 | ```ruby 63 | page.assert_all_of_selectors('elemento') 64 | ``` 65 | 66 | ## assert_none_of_selectors 67 | 68 | Afirma que nenhum dos seletores fornecidos está presente na página ou nos descendentes do nó atual. 69 | 70 | ```ruby 71 | page.assert_none_of_selector('elemento') 72 | ``` 73 | 74 | ## assert_matches_selector 75 | 76 | Afirma que o current_node corresponde a um determinado seletor. 77 | 78 | ```ruby 79 | page.assert_matches_selector('elemento') 80 | ``` 81 | 82 | ## assert_selector 83 | 84 | Afirma que um determinado seletor está na página ou um descendente do nó atual. 85 | 86 | ```ruby 87 | page.assert_selector('elemento') 88 | ``` 89 | 90 | ## assert_text 91 | 92 | Afirma que a página ou o nó atual possui o conteúdo de texto especificado, ignorando quaisquer tags HTML. 93 | 94 | ```ruby 95 | page.assert_text('elemento') 96 | ``` 97 | 98 | ## assert_title 99 | 100 | Afirma que a página tem o título dado. 101 | 102 | ```ruby 103 | page.assert_title('titulo') 104 | ``` 105 | 106 | ------------------------------------------------------------------------------- 107 | ## Asserts de negação 108 | 109 | ## assert_not_matches_selector 110 | 111 | Afirma que o current_node não corresponde a um determinado seletor. 112 | 113 | ```ruby 114 | page.assert_not_matches_selector('elemento') 115 | ``` 116 | 117 | ## assert_no_selector 118 | 119 | Afirma que um determinado seletor não está na página ou descendente do nó atual.. 120 | 121 | ```ruby 122 | page.assert_no_selector('elemento') 123 | ``` 124 | 125 | ## assert_no_text 126 | 127 | Afirma que a página ou o nó atual não tem o conteúdo de texto especificado, ignorando quaisquer tags HTML. 128 | 129 | ```ruby 130 | page.assert_no_text('elemento') 131 | ``` 132 | 133 | ## assert_no_title 134 | 135 | Afirma que a página não tem o título dado. 136 | 137 | ```ruby 138 | page.assert_no_title('titulo') 139 | ``` 140 | 141 | ------------------------------------------------------------------------------- 142 | 143 | ## Validaçōes com Has 144 | 145 | ## has_checked_field? 146 | 147 | Verifica se a página ou o nó atual tem um botão de opção ou caixa de seleção com o rótulo, valor ou ID fornecido, que está atualmente marcado. 148 | 149 | ```ruby 150 | page.has_checked_field?('elemento') 151 | ``` 152 | 153 | ## has_select? 154 | 155 | Verifica se a página ou o nó atual tem um campo de seleção com o rótulo, o nome ou o ID fornecido. 156 | 157 | ```ruby 158 | page.has_select?('elemento') 159 | ``` 160 | 161 | ## has_selector? 162 | 163 | Verifica se um determinado seletor está na página ou um descendente do nó atual. 164 | 165 | ```ruby 166 | page.has_selector?('elemento') 167 | ``` 168 | 169 | ## has_table? 170 | 171 | Verifica se a página ou o nó atual possui uma tabela com o ID ou a legenda especificada 172 | 173 | ```ruby 174 | page.has_table?('elemento') 175 | ``` 176 | 177 | ## has_text? 178 | 179 | Verifica se a página ou o nó atual tem o conteúdo de texto especificado, ignorando todas as tags HTML. 180 | 181 | ```ruby 182 | page.has_text?('elemento') 183 | ``` 184 | 185 | ## has_button? 186 | 187 | Verifica se a página ou o nó atual possui um botão com o texto, valor ou id fornecido. 188 | 189 | ```ruby 190 | page.has_button?('elemento') 191 | ``` 192 | 193 | ## has_unchecked_field? 194 | 195 | Verifica se a página ou o nó atual tem um botão de opção ou caixa de seleção com o rótulo, valor ou ID fornecido, que está atualmente desmarcado. 196 | 197 | ```ruby 198 | page.has_unchecked_field?('elemento') 199 | ``` 200 | 201 | ## has_xpath? 202 | 203 | Verifica se uma determinada expressão XPath está na página ou um descendente do nó atual. 204 | 205 | ```ruby 206 | page.has_xpath?('elemento') 207 | ``` 208 | 209 | ## has_css? 210 | 211 | Verifica se um determinado seletor de CSS está na página ou um descendente do nó atual. 212 | 213 | ```ruby 214 | page.has_css?('elemento') 215 | ``` 216 | 217 | ## has_field? 218 | 219 | Verifica se a página ou o nó atual tem um campo de formulário com o rótulo, o nome ou o ID fornecido. 220 | 221 | ```ruby 222 | page.has_field?('elemento') 223 | ``` 224 | 225 | ## has_link? 226 | 227 | Verifica se a página ou o nó atual tem um link com o texto ou o ID fornecido. 228 | 229 | ```ruby 230 | page.has_link?('elemento') 231 | ``` 232 | 233 | ## has_title? 234 | 235 | Afirma que a página tem o título dado. 236 | 237 | ```ruby 238 | page.has_title?('titulo') 239 | ``` 240 | 241 | ------------------------------------------------------------------------------- 242 | 243 | ## Negaçōes com Has_no 244 | 245 | 246 | ## has_no_title? 247 | 248 | Verifica se a página não tem o título dado. 249 | 250 | ```ruby 251 | page.has_no_title('titulo') 252 | ``` 253 | 254 | ## has_no_button? 255 | 256 | Verifica se a página ou o nó atual não possui um botão com o texto, valor ou id fornecido. 257 | 258 | ```ruby 259 | page.has_no_button?('elemento') 260 | ``` 261 | 262 | ## has_no_checked_field? 263 | 264 | Verifica se a página ou o nó atual não tem nenhum botão de opção ou caixa de seleção com o rótulo, valor ou ID fornecido, que está atualmente marcado. 265 | 266 | ```ruby 267 | page.has_no_checked_field?('elemento') 268 | ``` 269 | 270 | ## has_no_css? 271 | 272 | Verifica se um determinado seletor de CSS não está na página ou um descendente do nó atual. 273 | 274 | ```ruby 275 | page.has_no_css?('elemento') 276 | ``` 277 | 278 | ## has_no_field? 279 | 280 | Verifica se a página ou o nó atual não possui um campo de formulário com o rótulo, nome ou ID fornecido. 281 | 282 | ```ruby 283 | page.has_no_field?('elemento') 284 | ``` 285 | 286 | ## has_no_link? 287 | 288 | Verifica se a página ou o nó atual não tem link com o texto ou o ID fornecido. 289 | 290 | ```ruby 291 | page.has_no_link?('elemento') 292 | ``` 293 | 294 | ## has_no_select? 295 | 296 | Verifica se a página ou o nó atual não tem campo de seleção com o rótulo, nome ou id fornecido. 297 | 298 | ```ruby 299 | page.has_no_select?('elemento') 300 | ``` 301 | 302 | ## has_no_selector? 303 | 304 | Verifica se um determinado seletor não está na página ou um descendente do nó atual. 305 | 306 | ```ruby 307 | page.has_no_selector?('elemento') 308 | ``` 309 | 310 | ## has_no_table? 311 | 312 | Verifica se a página ou o nó atual não possui tabela com o ID ou legenda especificada. 313 | 314 | ```ruby 315 | page.has_no_table?('elemento') 316 | ``` 317 | 318 | ## has_no_text? 319 | 320 | Verifica se a página ou o nó atual não possui o conteúdo de texto especificado, ignorando qualquer tag HTML e normalizando o espaço em branco. 321 | 322 | ```ruby 323 | page.has_no_text?('elemento') 324 | ``` 325 | 326 | ## has_no_unchecked_field? 327 | 328 | Verifica se a página ou o nó atual não tem botão de opção ou caixa de seleção com o rótulo, valor ou ID fornecido, que está atualmente desmarcado. 329 | 330 | ```ruby 331 | page.has_no_unchecked_field?('elemento') 332 | ``` 333 | 334 | ## has_no_xpath? 335 | 336 | Verifica se uma determinada expressão XPath não está na página ou descendente do nó atual. 337 | 338 | ```ruby 339 | page.has_no_xpath?('elemento') 340 | ``` 341 | 342 | ------------------------------------------------------------------------------- 343 | 344 | ## Validando com matches_css 345 | 346 | ## matches_css? 347 | 348 | Verifica se o nó atual corresponde ao seletor de CSS especificado. 349 | 350 | ```ruby 351 | page.matches_css?('elemento') 352 | @element = find('elemento') 353 | expect(@element).to matches_css('elemento') 354 | expect(@element.matches_css?('elemento')).to be true 355 | ``` 356 | 357 | ## matches_selector? 358 | 359 | Verifica se o nó atual corresponde ao seletor especificado. 360 | 361 | ```ruby 362 | page.matches_selector?('elemento') 363 | @element = find('elemento') 364 | expect(@element).to matches_selector('elemento') 365 | expect(@element.matches_selector?('elemento')).to be true 366 | ``` 367 | 368 | ## matches_xpath? 369 | 370 | Verifica se o nó atual corresponde a determinada expressão XPath. 371 | 372 | ```ruby 373 | page.matches_xpath?('elemento') 374 | @element = find('elemento') 375 | expect(@element).to matches_xpath('elemento') 376 | expect(@element.matches_xpath?('elemento')).to be true 377 | ``` 378 | 379 | ------------------------------------------------------------------------------ 380 | 381 | ## Negando com not_matches 382 | 383 | ## not_matches_css? 384 | 385 | Verifica se o nó atual não corresponde ao seletor de CSS fornecido. 386 | 387 | ```ruby 388 | page.not_matches_css?('elemento') 389 | @element = find('elemento') 390 | expect(@element).to not_matches_css('elemento') 391 | expect(@element.not_matches_css?('elemento')).to be true 392 | ``` 393 | 394 | ## not_matches_selector? 395 | Verifica se o nó atual não corresponde ao dado seletor. O uso é idêntico ao has_selector?. 396 | 397 | ```ruby 398 | page.not_matches_selector?('elemento') 399 | @element = find('elemento') 400 | expect(@element).to not_matches_selector('elemento') 401 | expect(@element.not_matches_selector?('elemento')).to be true 402 | ``` 403 | 404 | ## not_matches_xpath? 405 | 406 | Verifica se o nó atual não corresponde à expressão XPath fornecida. 407 | 408 | ```ruby 409 | page.not_matches_xpath?('elemento') 410 | @element = find('elemento') 411 | expect(@element).to not_matches_xpath('elemento') 412 | expect(@element.not_matches_xpath?('elemento')).to be true 413 | ``` 414 | 415 | ------------------------------------------------------------------------------- 416 | 417 | ## Opçōes para auxiliares para matchers. 418 | 419 | ** Essas opçōes não são para todos o comandos não, sugiro ir na domcumentação e ver qual comando comando usa as opcōes nesse [Link](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers) 420 | 421 | 422 | **:count** — Número de vezes que o texto deve ocorrer 423 | 424 | **:minimum** — Número mínimo de vezes que o texto deve ocorrer 425 | 426 | **:maximum** — Número máximo de vezes que o texto deve ocorrer 427 | 428 | **:between** — Intervalo de horas que deve conter o número de vezes que o texto ocorre 429 | 430 | **:wait** — Tempo máximo que o Capybara esperará pelo texto para eq/match dado o argumento string/regexp 431 | 432 | **:exact** — Se o texto deve ser uma correspondência exata ou apenas substring 433 | 434 | **:with** — O conteúdo de texto do campo ou um Regexp para corresponder 435 | 436 | **:type** — O atributo type do campo 437 | 438 | **:options** — Opções que devem estar contidas nesta caixa de seleção 439 | 440 | **:with_options** — Conjunto parcial de opções que devem estar contidas nesta caixa de seleção 441 | 442 | **:selected** — Opções que devem ser selecionadas 443 | 444 | **:with_selected** — Conjunto parcial de opções que devem ser minimamente selecionadas 445 | 446 | 447 | **Vamos para o próximo post** [Validando elementos com rspec matchers](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/08-validacoes_com_rspec_matchers.md); 448 | 449 | ------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /tests/Capybara/08-validacoes_com_rspec_matchers.md: -------------------------------------------------------------------------------- 1 | ## Validando com Rspec Matcher 2 | 3 | ------------------------------------------------------------------------------- 4 | 5 | ## have_all_of_selectors 6 | 7 | Verifica se os elementos correspondentes a um grupo de seletores existem . 8 | 9 | ```ruby 10 | expect(@elemento).to have_all_of_selectors('//p') 11 | ``` 12 | 13 | ## have_button 14 | Verifica se a página ou o nó atual possui um botão com o texto, valor ou id fornecido. 15 | 16 | ```ruby 17 | expect(@elemento).to have_button('//p') 18 | ``` 19 | 20 | ## have_checked_field 21 | Se a página ou o nó atual tiver um botão de opção ou uma caixa de seleção com o rótulo, valor ou ID fornecido, que está marcado no momento. 22 | 23 | ```ruby 24 | expect(@elemento).to have_checked_field('//p') 25 | ``` 26 | 27 | ## have_css 28 | Verifica se um determinado seletor de CSS está na página ou um descendente do nó atual. 29 | 30 | ```ruby 31 | expect(@elemento).to have_css('//p') 32 | ``` 33 | 34 | ## have_current_path 35 | Afirma que a página tem o caminho fornecido 36 | 37 | ```ruby 38 | expect(@elemento).to have_current_path('//p') 39 | ``` 40 | 41 | ## have_field 42 | Verifica se a página ou o nó atual tem um campo de formulário com o rótulo, o nome ou o ID fornecido. 43 | 44 | ```ruby 45 | expect(@elemento).to have_field('//p') 46 | ``` 47 | 48 | ## have_link 49 | 50 | Verifica se a página ou o nó atual tem um link com o texto ou o ID fornecido. 51 | 52 | ```ruby 53 | expect(@elemento).to have_link('//p') 54 | ``` 55 | 56 | ## have_none_of_selectors 57 | 58 | Afirma que nenhum dos seletores fornecidos está presente na página ou nos descendentes do nó atual. 59 | 60 | ```ruby 61 | expect(@elemento).to have_none_of_selectors('//p') 62 | ``` 63 | 64 | ## have_select 65 | 66 | Verifica se a página ou o nó atual tem um campo de seleção com o rótulo, o nome ou o ID fornecido. 67 | 68 | ```ruby 69 | expect(@elemento).to have_select('//p') 70 | ``` 71 | 72 | ## have_selector 73 | 74 | Afirma que um determinado seletor está na página ou um descendente do nó atual. 75 | 76 | ```ruby 77 | expect(@elemento).to have_selector('//p') 78 | ``` 79 | 80 | ## have_table 81 | 82 | Verifica se a página ou o nó atual tem uma tabela com o ID ou legenda fornecida 83 | 84 | ```ruby 85 | expect(@elemento).to have_table('//p') 86 | ``` 87 | 88 | ## have_text 89 | 90 | Afirma que a página ou o nó atual possui o conteúdo de texto especificado, ignorando quaisquer tags HTML. 91 | 92 | ```ruby 93 | expect(@elemento).to have_text('//p') 94 | ``` 95 | 96 | ## have_title 97 | 98 | Verifica se um determinado título esta na página. 99 | 100 | ```ruby 101 | expect(@elemento).to have_title('//p') 102 | ``` 103 | 104 | ## have_unchecked_field 105 | 106 | Verifica se uma determinada expressão XPath está na página ou um descendente do nó atual. 107 | 108 | ```ruby 109 | expect(@elemento).to have_unchecked_field('//p') 110 | ``` 111 | 112 | ## have_xpath 113 | 114 | Verifica se uma quantia determinada XPath está na página ou descendente do seu atual. 115 | 116 | ```ruby 117 | expect(@elemento).to have_xpath('//p') 118 | ``` 119 | 120 | 121 | ## match_css 122 | 123 | Afirma que o current_node corresponde a um determinado seletor 124 | 125 | ```ruby 126 | expect(find('#zone')).to match_css('elemento') 127 | ``` 128 | 129 | ## match_selector 130 | 131 | Afirma que o current_node corresponde a um determinado seletor 132 | 133 | ```ruby 134 | expect(find('#zone')).to match_selector('elemento') 135 | ``` 136 | 137 | ## match_xpath 138 | 139 | Correspondente RSpec para saber se o elemento atual corresponde a um determinado seletor de xpath. 140 | 141 | ```ruby 142 | expect(find('#zone')).to match_xpath('elemento') 143 | ``` 144 | 145 | ------------------------------------------------------------------------------- 146 | 147 | 148 | **Vamos para o próximo post** [Janelas, Modal, Alerts e Iframe](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/09-janelas_modal_alerts_iframe.md); -------------------------------------------------------------------------------- /tests/Capybara/09-janelas_modal_alerts_iframe.md: -------------------------------------------------------------------------------- 1 | ## Janelas,Modal,Alerts e Iframe 2 | ----------------------------------------------------------------------------------------- 3 | 4 | ## Janela 5 | 6 | ## close_window 7 | 8 | Método para fechar a janela do navegador 9 | 10 | ```ruby 11 | close_window 12 | ``` 13 | 14 | ## current_window 15 | 16 | Janela corrente. 17 | 18 | ```ruby 19 | page.current_window.resize_to(x, y) 20 | ``` 21 | 22 | ## maximize_window 23 | 24 | Método para maximizar a janela. 25 | 26 | ```ruby 27 | page.current_window.maximize_window 28 | ``` 29 | 30 | ## open_new_window 31 | 32 | Método para abrir uma janela. 33 | 34 | ```ruby 35 | @session.open_new_window 36 | ``` 37 | 38 | ## refresh 39 | 40 | Método para dar um refresh na tela. 41 | 42 | ```ruby 43 | page.driver.browser.navigate.refresh 44 | ``` 45 | 46 | ## go_back 47 | 48 | Retroceda uma única entrada no histórico do navegador. 49 | 50 | ```ruby 51 | page.go_back 52 | ``` 53 | 54 | ## go_forward 55 | 56 | Avançar uma única entrada no histórico do navegador. 57 | 58 | ```ruby 59 | page.go_forward 60 | ``` 61 | 62 | ## resize_window_to 63 | 64 | Método para abrir uma ajustar o tamanho da tela desejada. 65 | 66 | ```ruby 67 | page.current_window.resize_window_to(x, y) 68 | ``` 69 | 70 | ## window_size 71 | 72 | Método para abrir uma ajustar o tamanho da tela desejada. 73 | 74 | ```ruby 75 | page.current_window.window_size(x, y) 76 | ``` 77 | 78 | ## window_opened_by 79 | 80 | Obter a janela que foi aberta pelo bloco passado. 81 | 82 | ```ruby 83 | janela = window_opened_by do 84 | click_link 'Clique aqui' 85 | end 86 | ``` 87 | 88 | ## windows 89 | 90 | Pega todas as janelas abertas 91 | 92 | ```ruby 93 | page.windows 94 | ``` 95 | 96 | ## switch_to_window 97 | 98 | Janela que foi para escolhida. 99 | 100 | ```ruby 101 | switch_to_window windows.last 102 | ``` 103 | 104 | ## within_window 105 | 106 | Bloco utilizado para fazer ações em determinada janela. 107 | 108 | ```ruby 109 | janela = window_opened_by do 110 | click_link 'Clique aqui' 111 | end 112 | 113 | within_window janela do 114 | 115 | expect(current_url).to eq 'https://automacaocombatista.herokuapp.com/mudancadefoco/newwindow' 116 | @mensagem = find('.red-text.text-darken-1.center') 117 | expect(@mensagem.text).to eq 'Você Abriu uma nova janela!!' 118 | janela.close 119 | end 120 | ``` 121 | 122 | ## window_handles 123 | 124 | Método para pegar as janelas abertas existentes 125 | 126 | ```ruby 127 | window_before = driver.window_handles[0] 128 | window_after = driver.window_handles[1] 129 | driver.switch_to_window(window_after) 130 | ``` 131 | 132 | ------------------------------------------------------------------------------ 133 | 134 | ## Modal 135 | 136 | ## within 137 | Executa o bloco especificado dentro do contexto de um nó. 138 | 139 | ```ruby 140 | within('div#delivery-address') do 141 | fill_in('Street', with: '12 Main Street') 142 | end 143 | ``` 144 | 145 | ## accept_modal 146 | 147 | Execute o bloco e aceite o modal aberto. 148 | 149 | ```ruby 150 | page.accept_modal 151 | ``` 152 | 153 | ## dismiss_modal 154 | 155 | Execute o bloco e, em seguida, descarte o modal aberto. 156 | 157 | ```ruby 158 | page.dismiss_modal 159 | ``` 160 | 161 | ------------------------------------------------------------------------------ 162 | ## Iframe 163 | 164 | ## within_frame 165 | 166 | Execute o bloco especificado dentro do iframe fornecido usando o quadro, o nome / id ou o índice do quadro. 167 | 168 | ```ruby 169 | within_frame 'random' do 170 | expect(page).to have_content 'content' 171 | end 172 | ``` 173 | 174 | ------------------------------------------------------------------------------ 175 | ## Alerts 176 | 177 | ## accept_alert 178 | 179 | Execute o bloco, aceitando um alerta. 180 | 181 | ```ruby 182 | page.accept_alert 183 | ``` 184 | 185 | ## accept_confirm 186 | 187 | Executa o bloco, aceitando a confirmação. 188 | 189 | ```ruby 190 | page.accept_confirm 191 | ``` 192 | 193 | ## accept_prompt 194 | 195 | Executa o bloco, aceitando a confirmação, opcionalmente respondendo ao prompt. 196 | 197 | 198 | ```ruby 199 | page.accept_prompt(with: 'bruno batista') 200 | ``` 201 | 202 | ## dismiss_confirm 203 | 204 | Executa o bloco, aceitando a confirmação. 205 | 206 | ```ruby 207 | page.dismiss_confirm 208 | ``` 209 | 210 | ## dismiss_prompt 211 | 212 | Execute o bloco, dispensando um prompt 213 | 214 | ```ruby 215 | page.dismiss_prompt 216 | ``` 217 | 218 | ------------------------------------------------------------------------------ 219 | 220 | ## Outros 221 | 222 | ## within_fieldset 223 | 224 | Execute o bloco dado dentro de um determinado fieldset dado o id ou legenda daquele fieldset. 225 | 226 | ```ruby 227 | within_fieldset 'random' do 228 | expect(page).to have_content 'content' 229 | end 230 | ``` 231 | 232 | ## within_table 233 | 234 | Execute o bloco dado dentro de uma tabela específica, dado o id ou legenda dessa tabela. 235 | 236 | ```ruby 237 | within_table 'random' do 238 | expect(page).to have_content 'content' 239 | end 240 | ``` 241 | 242 | **Vamos para o próximo post** [Métodos de screenchots](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/10-metodos_screenshots.md); -------------------------------------------------------------------------------- /tests/Capybara/10-metodos_screenshots.md: -------------------------------------------------------------------------------- 1 | ## Métodos para screenshots 2 | ------------------------------------------------------------------------------- 3 | 4 | ## save_and_open_page 5 | Salve um instantâneo da página e abra-o em um navegador para inspeção. 6 | 7 | ```ruby 8 | page.save_and_open_page 9 | ``` 10 | 11 | ## save_and_open_screenshot 12 | Salve uma captura de tela da página e abra-a para inspeção. 13 | 14 | ```ruby 15 | page.save_and_open_screenshot 16 | ``` 17 | 18 | ## save_page 19 | Salvar um instantâneo da página. 20 | 21 | ```ruby 22 | page.save_page 23 | ``` 24 | 25 | ## save_screenshot 26 | Salvar uma captura de tela da página. 27 | 28 | ```ruby 29 | page.save_screenshot 30 | ``` 31 | 32 | **Vamos para o próximo post** [Web responsiva com Capybara](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/11-web_responsiva_capybara.md); -------------------------------------------------------------------------------- /tests/Capybara/11-comandos_javascript.md: -------------------------------------------------------------------------------- 1 | # Comandos JavaScript 2 | 3 | ## evaluate_async_script 4 | Avalie o JavaScript fornecido e obtenha o resultado de uma função de retorno de chamada que será passada como o último argumento para o script. 5 | 6 | ```ruby 7 | page.evaluate_async_script('script') 8 | ``` 9 | 10 | ## evaluate_script 11 | Avalie o JavaScript fornecido e retorne o resultado. 12 | 13 | 14 | ```ruby 15 | page.evaluate_script('script') 16 | ``` 17 | 18 | ## execute_script 19 | Execute o script fornecido, não retornando um resultado. 20 | 21 | ```ruby 22 | page.execute_script('script') 23 | ``` 24 | 25 | ## trigger 26 | Acione qualquer evento no elemento atual, por exemplo, eventos de mouseover ou foco. 27 | 28 | ```ruby 29 | page.find('element_name').trigger(:mouseover) 30 | ``` 31 | 32 | **Vamos para o próximo post** [Comandos Web responsiva com Capybara](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/12-web_responsiva_capybara.md); 33 | -------------------------------------------------------------------------------- /tests/Capybara/capybara.md: -------------------------------------------------------------------------------- 1 | 2 | ## FALTA EDITAR 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/Capybara/comandos_capybara.md: -------------------------------------------------------------------------------- 1 | # Capybara 2 | 3 | 1. [Introdução](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/01-introducao.md); 4 | 2. [Instalando Drivers](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/02-instalando_drivers.md); 5 | 3. [Configuração](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/03-configurando_projeto.md); 6 | 4. [Acessando url](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/04-acessando_url.md); 7 | 5. [Buscando elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/05-buscando_elementos.md); 8 | 6. [Realizando Açōes](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/06-realizando_acoes.md); 9 | 7. [Validando elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/07-validando_elementos.md); 10 | 8. [Validaçōes com Rspec Matchers](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/08-validacoes_com_rspec_matchers.md); 11 | 9. [Janela, Modal, Alerts e Iframe](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/09-janelas_modal_alerts_iframe.md); 12 | 10. [Métodos de screenchots](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/10-metodos_screenshots.md); 13 | 11. [Comandos Javascript](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/11-comandos_javascript.md); 14 | 15 | MAIS EM BREVE... -------------------------------------------------------------------------------- /tests/CircleCi/comandos_circleci.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Codeship/comandos_codeship.md: -------------------------------------------------------------------------------- 1 | # Mas primeiro vamos falar o que é a integração contínua? 2 | 3 | A integração contínua é uma prática de desenvolvimento de software de DevOps em que os desenvolvedores, com frequência, juntam suas alterações de código em um repositório central. Depois disso, criações e testes são executados. Geralmente, a integração contínua se refere ao estágio de criação ou integração do processo de lançamento de software, além de originar um componente de automação (ex.: uma CI ou serviço de criação) e um componente cultural (ex.: aprender a integrar com frequência). 4 | 5 | ## E qual principal objetivo da integração contínua? 6 | 7 | Os principais objetivos da integração contínua são encontrar e investigar bugs mais rapidamente, melhorar a qualidade do software e reduzir o tempo que leva para validar e lançar novas atualizações de software. 8 | 9 | ## O que é Codeship? 10 | 11 | O Codeship é um serviço de entrega contínua hospedado que se concentra na velocidade, confiabilidade e simplicidade. Você configura o Codeship para criar e implantar seu aplicativo do GitHub para o cenário ou a plataforma de produção de sua escolha. 12 | 13 | O serviço oferece uma variedade de poderosas opções de configuração. Atualmente, o Codeship é integrado aos populares gestores de código fonte GitHub e Bitbucket. Ele suporta uma variedade de linguagens de programação (Ruby on Rails, Node.js , PHP, Java, Go, Dart, etc.) e plataformas de implantação (Amazon Web Services, Heroku, Google App Engine, etc.) 14 | 15 | A prática de integração contínua envolve repetidos testes automatizados e fusão de código com notificações para alertar os desenvolvedores para problemas em seu código em tempo real. O Codeship combina isso com a prática de entrega contínua , que prevê a implantação regular de códigos uma vez que as mudanças passaram testes automatizados. 16 | 17 | 18 | ## Então vamos configurar nosso Codeship? 19 | 20 | ## 1- Passo 21 | 22 | Crie uma conta no codeship é de graça: 23 | 24 | https://app.codeship.com/registrations/new?utm_source=NavBar 25 | 26 | ## 2- Passo 27 | 28 | Escolha qual o repositório que você usa, no meu caso eu uso github, então irei usá-lo nos exemplos, mas o conceito é a mesma coisa para os outros repositórios. 29 | 30 | ## 3- Passo 31 | 32 | Nesta tela você irá colocar o link do seu projeto, mesma coisa como se você fosse clonar o seu projeto. Basta copiar o link do seu pojeto e colar na página do codeship. 33 | 34 | ## 4- Passo 35 | 36 | Nessa nossa aula iremos usa a versão básica 37 | 38 | ## 5- Passo 39 | 40 | Vamos escolher qual linguagem usaremos no codeship,nesse post usaremos a linguagem Ruby 41 | 42 | Depois de escolher a linguagem o codeship já irá criar uns comandos básicos. 43 | 44 | O codeship já vem com vários pacotes já instalados nele por padrão,se precisar saber quais são basta acessar esse link abaixo: 45 | 46 | https://documentation.codeship.com/basic/builds-and-configuration/packages/ 47 | 48 | Os comandos de configuração que usaremos pra rodar os testes automatizados são: 49 | 50 | ``` 51 | rvm use 2.4.2 — install 52 | export CHROMEDRIVER_VERSION=2.33 53 | rvm use $(cat .ruby-version) –install 54 | ``` 55 | 56 | Estamos instalando a versão 2.4.2 do RVM 57 | 58 | ``` 59 | rvm use 2.4.2 — install 60 | ``` 61 | 62 | Dando um update no chromedriver e setando a versão a ser usada. 63 | 64 | (OBS: O Codeship já vem de padrão instalado o chromedriver 2.31) 65 | 66 | ``` 67 | export CHROMEDRIVER_VERSION=2.33 68 | ``` 69 | 70 | Setando a versão do ruby 71 | 72 | ``` 73 | rvm use $(cat .ruby-version) –install 74 | ``` 75 | 76 | ## 6- Passo 77 | 78 | Depois de ter configurando o ambiente agora iremos configurar os comandos para executar os testes no segundo terminal abaixo. 79 | 80 | ``` 81 | cd src 82 | bundle install 83 | bundle exec cucumber 84 | ``` 85 | 86 | Estou entrando dentro da pasta onde está o meu arquivo gemfile 87 | 88 | ``` 89 | cd src 90 | ``` 91 | Instalando as dependencias que eu selecionei no meu gemfile 92 | 93 | ``` 94 | bundle install 95 | ``` 96 | 97 | Executando o comando para rodar o meu projeto 98 | 99 | ``` 100 | bundle exec cucumber 101 | ``` 102 | 103 | Depois basta salvar que o codeship irá rodar automaticamente os seus testes. 104 | 105 | A clicar em cima do projeto vocês veram um dashboard como este abaixo. 106 | 107 | Ao finalizar os testes terá 3 tipos de situações : 108 | 109 | Success — Este é o melhor caso onde todos os testes passaram. 110 | 111 | Error — Quando alguma coisa do codeship deu erro ou falhou. 112 | 113 | Failed — Quando seus testes falharam. 114 | 115 | ## Referências: 116 | 117 | https://medium.com/@brunobatista101/aprenda-a-fazer-integra%C3%A7%C3%A3o-cont%C3%ADnua-dos-seus-testes-automatizados-com-capybara-codeship-6463f4e2209e 118 | 119 | https://codeship.com/ -------------------------------------------------------------------------------- /tests/ConfiguracaoAndroid/configuracao_android.md: -------------------------------------------------------------------------------- 1 | Aqui iremos falar como configurar o Android em todos os sistemas operacionais. 2 | 3 | 1. [Configuração Android Linux](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoAndroid/configuracao_android_linux.md); 4 | 2. [Configuração Android Mac](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoAndroid/configuracao_android_mac.md); 5 | 3. [Configuração Android Windows](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoAndroid/configuracao_android_windows.md); 6 | -------------------------------------------------------------------------------- /tests/ConfiguracaoAndroid/configuracao_android_linux.md: -------------------------------------------------------------------------------- 1 | # Configuração no Linux 2 | 3 | No Linux, por possuirmos um gerenciador de pacotes, a coisa fica um pouco mais fácil. Caso você esteja utilizando o Ubuntu / Linux Mint, para preparar nosso ambiente, basta instalar os seguintes pacotes: 4 | 5 | ```ruby 6 | sudo apt-get install lib32z1 lib32ncurses5 lib32stdc++6 openjdk-8-jdk qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils 7 | ``` 8 | Caso esteja utilizando o Fedora, os pacotes são: 9 | 10 | ```ruby 11 | sudo dnf install glibc.i686 glibc-devel.i686 libstdc++.i686 zlib-devel.i686 ncurses-devel.i686 libX11-devel.i686 libXrender.i686 libXrandr.i686 java-1.8.0-openjdk-devel qemu-kvm 12 | ``` 13 | 14 | Outras distribuições podem ter estes pacotes com outros nomes, mas uma rápida busca pode trazer os correspondentes. O Linux não utiliza o HAXM para aceleração dos emuladores x86 – para isso, temos o KVM, um mecanismo de virtualização ligado ao kernel (caso o seu processador suporte). 15 | 16 | Em seguida, vamos baixar o Android Studio. Para Linux, o arquivo tem extensão .tar.gz e deve ser extraído para alguma pasta (como por exemplo, ~/Android). Feito isso, basta executar o arquivo studio.sh que encontra-se dentro da pasta bin. Na primeira execução, serão baixados os pacotes necessários para a SDK. Para encerrar, selecione no menu Configure a opção Create Desktop Entry para facilitar a execução do Android Studio a partir do seu menu de aplicativos (seja Unity, Gnome, KDE, etc.) 17 | 18 | O último passo é exportarmos a variável ANDROID_HOME e colocar os binários no Path. Para isso abra o arquivo ~/.bashrc ou, caso esteja utilizando o zshell, ~/.zshrc, e adicione as seguintes linhas. Caso tenha modificado o local da instalação da SDK do Android, ajuste o caminho: 19 | 20 | ```ruby 21 | export ANDROID_HOME="$HOME/Android/Sdk" 22 | export PATH="$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools" 23 | ``` 24 | 25 | Por fim, é opcional porém recomendada, a instalação do Git para controle de versão dos nossos projetos. 26 | 27 | ## REFERÊNCIAS: 28 | 29 | http://www.rafaeltoledo.net/configurando-o-ambiente-de-desenvolvimento-tutorial-android-1/ -------------------------------------------------------------------------------- /tests/ConfiguracaoAndroid/configuracao_android_mac.md: -------------------------------------------------------------------------------- 1 | # Configuração no OSX 2 | 3 | No OSX (Mac), a instalação é semelhante a que fizemos para o Windows. Primeiramente, baixe a JDK do site da Oracle. A instalação deve ocorrer sem maiores problemas, bastando seguir o wizard com o passo a passo da instalação. 4 | 5 | Em seguida, baixe o Android Studio. A partir do arquivo .dmg, a instalação é tranquila, seguindo o padrão para outros aplicativos do Mac. Ao executar pela primeira vez, as ferramentas serão baixadas e o HAXM será instalado. 6 | 7 | O último passo é a configuração das variáveis de ambiente. Contando que os caminhos padrão tanto do Java quanto da SDK do Android não foram alterados durante a instalação, adicione o seguinte conteúdo ao arquivo ~/.bash_profile (caso o arquivo não exista, crie-o). 8 | 9 | ```ruby 10 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home 11 | export ANDROID_HOME=$HOME/Library/Android/sdk 12 | export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools 13 | ``` 14 | 15 | Por último, opcionalmente mas fortemente recomendado, instale o Git (opte por utilizar o Homebrew, para instalar a versão mais recente). 16 | 17 | ## REFERÊNCIAS: 18 | 19 | http://www.rafaeltoledo.net/configurando-o-ambiente-de-desenvolvimento-tutorial-android-1/ -------------------------------------------------------------------------------- /tests/ConfiguracaoAndroid/configuracao_android_windows.md: -------------------------------------------------------------------------------- 1 | # Configuração no Windows 2 | 3 | O primeiro passo para a instalação do ambiente no Windows, é o download da JDK (Java Development Kit). Ela nos fornecerá a base de ferramentas para o desenvolvimento Java, que será utilizada também para o desenvolvimento dos apps Android também. Você pode baixar a JDK no site da Oracle. A instalação deve ocorrer sem problemas. 4 | 5 | O próximo passo consiste em baixarmos o Android Studio. Após baixar o .exe bundle (que já contém os itens básicos de SDK e emulador), basta seguir o procedimento de instalação normalmente como qualquer outro aplicativo. 6 | 7 | 8 | O último passo é exportarmos as variáveis de ambiente JAVA_HOME e ANDROID_HOME, para que possamos, quando necessário, também executar builds e comandos a partir do console. Primeiramente vamos exportar a ANDROID_HOME. Caso você não tenha alterado o local durante a instalação do Android Studio, o valor deve ser: 9 | 10 | ```ruby 11 | %LOCALAPPDATA%\Android\sdk 12 | ``` 13 | Em seguida, vamos exportar a JAVA_HOME. Novamente, se você não alterou o local da instalação do Java, o valor deve ser: 14 | 15 | ```ruby 16 | %ProgramFiles%\Java\jdk1.8.0_111 17 | ``` 18 | 19 | No momento que escrevo este post, a última versão do Java é a 8, revisão 111. Caso a versão que você instale seja outra, ajuste o caminho de acordo. 20 | 21 | Por fim, vamos adicionar os binários ao Path do sistema, para que sejam acessíveis através do console. Adicione ao Path as entradas 22 | 23 | ```ruby 24 | %ANDROID_HOME%\tools, %ANDROID_HOME%\platform-tools e %JAVA_HOME%\bin. 25 | ``` 26 | 27 | Para testar, valide que os comandos adb e javac são acessíveis no console. 28 | 29 | Durante a instalação do Android Studio, também deve ter sido instalado o HAXM (caso o seu processador seja compatível). O HAXM permitirá que vocẽ execute o emulador do Android com excelente desempenho. Outra boa opção de emulador é o Genymotion, porém para usos gerais, o emulador que acompanha a SDK do Android é suficiente. 30 | 31 | Por fim, opcional mas recomendado, instale o Git, que é hoje a ferramenta de versão mais utilizada. 32 | 33 | ## REFERÊNCIAS: 34 | 35 | http://www.rafaeltoledo.net/configurando-o-ambiente-de-desenvolvimento-tutorial-android-1/ -------------------------------------------------------------------------------- /tests/ConfiguracaoRuby/configuracao_ruby.md: -------------------------------------------------------------------------------- 1 | Aqui iremos falar como configurar o ruby em todos os sistemas operacionais. 2 | 3 | 1. [Instalando Ruby on Mac](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/instalando_ruby_mac.md); 4 | 2. [Instalando Ruby on Windows](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/instalando_ruby_windows.md); 5 | 3. [Instalando Ruby on Linux](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/instalando_ruby_linux.md); 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/ConfiguracaoRuby/instalando_ruby_linux.md: -------------------------------------------------------------------------------- 1 | # Como instalar Ruby no Ubuntu com Rbenv 2 | 3 | O rbenv fornece suporte para trabalhar versões específicas do aplicativo do Ruby, permite alterar o Ruby global para cada usuário e permite usar uma variável de ambiente para substituir a versão do Ruby. 4 | 5 | ## Pré-requisitos 6 | Este tutorial irá levá-lo através do processo de instalação do Ruby via rbenv. Para seguir este tutorial, você precisa ter um servidor Ubuntu 14.xx ou 16.xx e o usuário comum (não root). 7 | 8 | ## Update do Ubuntu e Dev Dependencies 9 | 10 | ```ruby 11 | sudo apt-get update 12 | ``` 13 | 14 | ``` 15 | sudo apt-get install git 16 | ``` 17 | 18 | Instalar Rbenv 19 | Com os seguintes comandos: 20 | 21 | ```ruby 22 | $ git clone https://github.com/rbenv/rbenv.git ~/.rbenv 23 | ``` 24 | 25 | ``` 26 | $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc 27 | ``` 28 | 29 | ``` 30 | $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc 31 | ``` 32 | 33 | ``` 34 | $ source ~/.bashrc 35 | ``` 36 | 37 | ``` 38 | $ type rbenv 39 | ``` 40 | 41 | ## Instalar Ruby Build 42 | 43 | ```ruby 44 | $ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build 45 | ``` 46 | 47 | ## Instalando o Ruby 48 | Este comando, deve carregar em cache a lista de versões disponíveis para instalação: 49 | 50 | ```ruby 51 | $ rbenv install -l 52 | ``` 53 | 54 | Agora instale a versão desejada (eu escolhe a versão 2.4.1) 55 | 56 | ```ruby 57 | $ rbenv install 2.4.2 58 | ``` 59 | 60 | Com o comando abaixo, você define a versão global do Ruby no sistema 61 | 62 | ```ruby 63 | $ rbenv global 2.4.2 64 | ``` 65 | 66 | Para verificar se deu tudo certo, digite o comando: 67 | 68 | ```ruby 69 | $ ruby -v 70 | ``` 71 | 72 | Deverá aparece algo como: 73 | 74 | ```ruby 75 | ruby 2.4.2 76 | ``` 77 | -------------------------------------------------------------------------------- /tests/ConfiguracaoRuby/instalando_ruby_mac.md: -------------------------------------------------------------------------------- 1 | # Instalando Ruby on Mac 2 | 3 | ## Instalando Homebrew 4 | Primeiro, precisamos instalar o Homebrew . O Homebrew nos permite instalar e compilar pacotes de software para MacOS. 5 | 6 | O Homebrew vem com um script de instalação muito simples. Quando solicitar que você instale o XCode CommandLine Tools, diga sim. 7 | 8 | Agora abra o Terminal e execute o seguinte comando: 9 | 10 | ```ruby 11 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 12 | ``` 13 | 14 | ## Instalando Ruby 15 | Agora que temos o Homebrew instalado, podemos usá-lo para instalar o Ruby. Nós vamos usar o rbenv para instalar e gerenciar nossas versões do Ruby. 16 | 17 | Para fazer isso, execute os seguintes comandos em seu Terminal: 18 | 19 | ```ruby 20 | brew install rbenv ruby-build 21 | echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile 22 | source ~/.bash_profile 23 | ``` 24 | 25 | # Instalando Ruby 2.4.2 26 | ``` 27 | rbenv install 2.4.2 28 | ``` 29 | 30 | ``` 31 | rbenv global 2.4.2 32 | ``` 33 | 34 | ``` 35 | ruby -v 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /tests/ConfiguracaoRuby/instalando_ruby_windows.md: -------------------------------------------------------------------------------- 1 | # Instalando Ruby e DevKit no Windows 2 | 3 | ## 1. CMD ou PowerShell? 4 | 5 | O fato é que vamos usar muita linha de comando, e como estamos no windows temos o CMD ou PowerShell, mas qual usar? 6 | 7 | Vamos usar o CMD mesmo, porem temos um "programinha" bem chique que da uma bela turbinada nele. o CMDER (Console Emutator). Com ele temos no Windows muitos comandos do linux e um Console bem agradável para trabalhar com linha de comando que inclusive funciona o Control C e Control V (isso é realmente bom). Até o editor de texto VIM vem junto no pacote de instalação full. Legal né? 8 | 9 | ## Segue abaixo os passos para instalação. 10 | 11 | 1) Faça download do pacote FULL no site http://cmder.net/ 12 | 13 | 2) Descompactar na pasta C:\tools\Cmder (tem que criar a pasta) 14 | 15 | 3) Executar o cmder.exe (cria um atalho e coloca onde tu quiser pra ficar mais pratico) 16 | 17 | ## 2. Instalando Ruby 64 Bits 18 | a) Fazer download da versão 2.4.2 x64 http://rubyinstaller.org/downloads/ 19 | 20 | b) Instalar no diretório C:\Ruby24-x64 21 | 22 | c) Antes de clicar em Install marca todas as opções. 23 | 24 | c) Feche o Console do CMDER, e abre de novo, em seguida, digite o comando ruby –v, se der tudo certo você vai ver o seguinte resultado: 25 | 26 | ```ruby 27 | ruby 2.4.2 28 | ``` 29 | -------------------------------------------------------------------------------- /tests/Cucumber/01-introducao_cucumber.md: -------------------------------------------------------------------------------- 1 | # Introdução ao Cucumber 2 | 3 | Cucumber é uma ferramenta que suporta o Desenvolvimento Guiado por Comporamento (BDD - Behavior-driven Development). 4 | O Cucumber faz a leitura das especificações em texto e valida se o que o software está executando está de acordo com a especificação. A especificação consiste em diversos cenários ou exemplos. 5 | Cada cenário é uma lista de passos para o Cucumber trabalhar em cima. O Cucumber consegue verificar se o Software está entregando o negócio conforme a especificação e reporta com ✅ se o cenário passou ou com ❌ se o cenário quebrou. 6 | 7 | ## Introdução ao BDD. 8 | 9 | O BDD foi concebido por Dan North, a partir de uma insatisfação com a falta de informações dos testes de TDD (“Test driven development”). Dan queria saber mais sobre o que deveria ser testado e como esse teste deveria ser realizado. A ideia principal do BDD é possibilitar que as funcionalidades do sistema sejam escritas em linguagem natural. 10 | 11 | O BDD é uma abordagem que serve para integrar os testes com as regras de negócios e também com a linguagem de programação focando no comportamento do software usando uma [linguagem ubíqua](https://pt.linkedin.com/pulse/domain-driven-design-linguagem-ub%C3%ADqua-veranildo-veras) (Ubiquitous Language). Assim melhorando a comunicação com as equipes. 12 | 13 | O BDD usa várias linguagens mas nesse tutorial iremos dar foco em uma linguagem chamada Gherkin. 14 | 15 | O Gherkin é uma linguagem que foi criada para descrições de comportamento. Ela tem a capacidade de remover detalhes da lógica de programação e focar no comportamento que uma funcionalidade deve ter. Ela suporta várias linguagens. Veja abaixo um exemplo de uma funcionalidade na linguagem gherkin. 16 | 17 | Exemplo: 18 | 19 | ```ruby 20 | #language: pt-br 21 | Funcionalidade: Fazer Login 22 | 23 | Eu, como usário 24 | Desejo fazer login na aplicação 25 | 26 | Cenário: Fazer login na aplicação 27 | Dado que eu tenho um usuário e senha 28 | Quando eu faço login 29 | Então eu verifico se estou logado na aplicação 30 | ``` 31 | 32 | ```ruby 33 | #language: pt-br <é usado par que a linguagem gherkin identifique o idioma português > 34 | 35 | Funcionalidade <é onde faz a descrição da funcionalidade> 36 | 37 | Como um 38 | 39 | Eu quero 40 | 41 | De modo que 42 | 43 | Cenário: 44 | 45 | Dado 46 | 47 | Quando 48 | 49 | Então 50 | ``` 51 | 52 | A linguagem Gherkin é independente de qualquer linguagem de programação. Pode ser utilizada para criar testes/software em java ,ruby , python etc. Basta colocar um .feature no nome do arquivo. 53 | 54 | ```ruby 55 | Ex: fazerLogin.feature 56 | ``` 57 | 58 | ## Vantagens 59 | 60 | - Maior entendimento do requisito proposto. 61 | - Menos tempo investido em escrita de casos de testes. 62 | - Mais tempo investido em análise de cobertura de testes. 63 | - Estes testes podem ser utilizados por desenvolvedores na automatização. 64 | - Fácil manutenção de templates. 65 | 66 | 67 | ### **Próximo post:** [Instalação do Cucumber](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/02-instalacao_cucumber.md); 68 | 69 | 70 | ## Referências: 71 | 72 | https://github.com/cucumber/cucumber 73 | https://medium.com/@brunobatista101/da-s%C3%A9rie-1-aprenda-cucumber-com-batista-1b75ba2fb0a5 74 | -------------------------------------------------------------------------------- /tests/Cucumber/02-instalacao_cucumber.md: -------------------------------------------------------------------------------- 1 | # Instalação do Cucumber 2 | 3 | Instalar o cucumber e bem simples, basta abrir o terminal e digitar o seguinte comando: 4 | 5 | ``` 6 | gem install cucumber 7 | ``` 8 | 9 | Depois de instalado para criar um projeto em cucumber basta digitar o seguinte comando em qual pasta voçê deseja que o projeto seja criado: 10 | 11 | ``` 12 | cucumber --init 13 | ``` 14 | 15 | Esse comando irá criar criar uma estrutura básica 16 | 17 | ``` 18 | create features 19 | create features/step_definitions 20 | create features/support 21 | create features/support/env.rb 22 | ``` 23 | 24 | Onde a pasta step... é onde colocamos os arquivos .rb 25 | 26 | Onde a pasta suport é onde fazemos nossas configurações 27 | 28 | Eu também adiciono a pasta 29 | 30 | ``` 31 | features/specs 32 | ``` 33 | Onde nela colocamos os arquivos .feature 34 | 35 | Vamos paro proximo post [Comandos Given When Then And But](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/03-given_when_then_but_and.md); 36 | 37 | ## Referências: 38 | 39 | https://github.com/cucumber/cucumber -------------------------------------------------------------------------------- /tests/Cucumber/03-given_when_then_but_and.md: -------------------------------------------------------------------------------- 1 | # Given(Dado) When(Quando) Then(Então) And(e) But(mas) 2 | 3 | Depois de ter feito a [Instalação do Cucumber](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/02-instalacao_cucumber.md); 4 | 5 | Agora vamos por em prática! 6 | 7 | Vamos criar nosso primeiro arquivo feature. 8 | Primeiro é preciso salvar o arquivo como ".feature". 9 | 10 | ``` 11 | login.feature 12 | ``` 13 | 14 | A linguagem gerkin ela pode ser escrita em vários idiomas,para os tutorias eu irei usar em pôrtugues mesmo pra o fácil aprendizado. 15 | 16 | Para podermos dizer qual linguagem sera utilizada temos que colocar o seguinte comando na primeira linha do arquivo: 17 | 18 | ``` 19 | # language: pt 20 | ``` 21 | 22 | Segundo passo e dizer qual a funcionalidade que iremos testar: 23 | 24 | ``` 25 | # language: pt 26 | 27 | Funcionalidade: Fazer Login 28 | 29 | ``` 30 | 31 | O cenarios do cucumber consistem em etapas, também conhecidas como Givens, Whens e Thens. 32 | 33 | O cucumber não distingue tecnicamente entre esses três tipos de etapas. No entanto, recomendamos que você faça! Essas palavras foram cuidadosamente selecionadas para seu propósito, e você deve saber qual é o propósito de entrar na mentalidade do BDD . 34 | 35 | Robert C. Martin escreveu uma ótima publicação sobre o conceito Given-When-Then do BDD, onde ele pensa neles como uma máquina de estados finitos. 36 | 37 | ## Given(Dado) 38 | 39 | O objetivo dos dados é colocar o sistema em um estado conhecido antes que o usuário (ou sistema externo) comece a interagir com o sistema (nas etapas Quando). Evite falar sobre a interação do usuário em dados. Se você criasse casos de uso, os dados seriam suas condições prévias. 40 | 41 | Exemplos: 42 | 43 | Crie registros (instâncias do modelo) / configure o estado do banco de dados. 44 | Está certo chamar a camada "dentro" da camada UI aqui (em Rails: converse com os modelos). 45 | Faça login em um usuário (Uma exceção à recomendação sem interação. As coisas que "aconteceram anteriormente" estão ok). 46 | E para todos os usuários Rails lá fora - recomendamos usar um dado com um argumento de tabela multilinha para configurar registros em vez de dispositivos elétricos. Desta forma, você pode ler o cenário e dar sentido a isso sem ter que procurar em outro lugar (nas luminárias). 47 | 48 | ## When(Quando) 49 | 50 | O objetivo de As etapas é descrever a ação-chave que o usuário executa (ou, usando a metáfora de Robert C. Martin, a transição do estado). 51 | 52 | Exemplos: 53 | 54 | Interagir com uma página web (Webrat / Watir / Selenium interação etc deve principalmente ir para quando passos). 55 | Interaja com algum outro elemento da interface do usuário. 56 | Desenvolver uma biblioteca? Chutando algum tipo de ação que tenha um efeito observável em outro lugar. 57 | 58 | ## Then(Então) 59 | 60 | O objetivo de Then steps é observar os resultados . As observações devem estar relacionadas ao valor / benefício da empresa na descrição do recurso. As observações também devem estar em algum tipo de saída - que é algo que vem de fora do sistema (relatório, interface de usuário, mensagens) e não algo que está profundamente enterrado dentro dela (que não tem valor comercial). 61 | 62 | Exemplos: 63 | 64 | Verifique se algo relacionado ao dado + Quando é (ou não) na saída 65 | Verifique se algum sistema externo recebeu a mensagem esperada (um e-mail com conteúdo específico foi enviado?) 66 | Embora possa ser tentador implementar, em seguida, etapas para apenas procurar no banco de dados - resista à tentação. Você só deve verificar o resultado que é observável para o usuário (ou sistema externo) e os bancos de dados geralmente não são. 67 | 68 | ## And,But(E,mas) 69 | 70 | Se você tem vários dados, whens ou thens você pode escrever 71 | 72 | ``` 73 | Cenário : Múltiplos Givens 74 | Dado um 75 | dado Dado outro 76 | dado Dado ainda outra coisa 77 | Quando eu abro meus olhos 78 | Então eu vejo algo 79 | Então eu não vejo outra coisa 80 | ``` 81 | 82 | Ou você pode fazê-lo ler mais fluentemente escrevendo 83 | 84 | ``` 85 | Cenário : Múltiplos Givens 86 | Dado uma coisa 87 | E outra coisa 88 | E ainda outra coisa 89 | Quando eu abro meus olhos 90 | Então eu vejo algo 91 | Mas eu não vejo outra coisa 92 | ``` 93 | 94 | Para passos de cucumber começando com E ou Mas são exatamente o mesmo tipo de etapas que todos os outros. 95 | 96 | Agora vamos continua com nossa feature que ficaria desse jeito 97 | 98 | 99 | ``` 100 | # language: pt 101 | 102 | Funcionalidade: Fazer Login 103 | 104 | Cenário: Fazer login com sucesso. 105 | Dado que eu tenha um usuário. 106 | Quando faço login. 107 | Então eu verifico se o login foi realizado. 108 | 109 | ``` 110 | 111 | Depois disso basta digitar o seguinte comando no terminal: 112 | 113 | ``` 114 | cucumber 115 | ``` 116 | 117 | O cucumber irá gerar os metódos em qual lnguagem você estiver usando, no nosso caso e ruby. 118 | 119 | Então o resultado será esse: 120 | 121 | ``` 122 | # language: pt 123 | Funcionalidade: Fazer Login 124 | 125 | Cenário: Fazer login com sucesso. #features/step_definitions/login.feature:5 126 | Dado que eu tenha um usuário. #features/step_definitions/login.feature:6 127 | Quando faço login. #features/step_definitions/login.feature:7 128 | Então eu verifico se o login foi realizado. #features/step_definitions/login.feature:8 129 | 130 | 1 scenario (1 undefined) 131 | 3 steps (3 undefined) 132 | 0m0.147s 133 | 134 | You can implement step definitions for undefined steps with these snippets: 135 | 136 | Dado("que eu tenha um usuário.") do 137 | pending # Write code here that turns the phrase above into concrete actions 138 | end 139 | 140 | Quando("faço login.") do 141 | pending # Write code here that turns the phrase above into concrete actions 142 | end 143 | 144 | Então("eu verifico se o login foi realizado.") do 145 | pending # Write code here that turns the phrase above into concrete actions 146 | end 147 | 148 | ``` 149 | 150 | Esse e o primeiro passo para se criar os steps onde o código abaixo será inserido em algum arquivo .rb e dentro dos metodos serem feito os comandos de automações. 151 | 152 | ``` 153 | Dado("que eu tenha um usuário.") do 154 | pending # Write code here that turns the phrase above into concrete actions 155 | end 156 | 157 | Quando("faço login.") do 158 | pending # Write code here that turns the phrase above into concrete actions 159 | end 160 | 161 | Então("eu verifico se o login foi realizado.") do 162 | pending # Write code here that turns the phrase above into concrete actions 163 | end 164 | ``` 165 | 166 | Vamos para o próximo post [Background](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/04-background.md); 167 | 168 | ## Referências: 169 | 170 | https://github.com/cucumber/cucumber 171 | -------------------------------------------------------------------------------- /tests/Cucumber/04-background.md: -------------------------------------------------------------------------------- 1 | # Background(Contexto) 2 | 3 | O Background permite que você adicione algum contexto aos cenários em um único recurso. A Background é muito parecido com um cenário contendo uma série de etapas. A diferença é quando é executado. O plano de fundo é executado antes de cada um dos seus cenários, mas após qualquer um dos antes de hooks . 4 | 5 | Exemplo: 6 | 7 | ``` 8 | #language: pt 9 | 10 | Funcionalidade: Suporte de vários sites 11 | 12 | Como um dono do site Mephisto Eu quero hospedar blogs para diferentes pessoas 13 | Para fazer gigantescas pilhas de dinheiro 14 | 15 | Contexto: 16 | Dado um administrador global chamado "Greg" E um blog chamado "Greg's anti-tax Rants" 17 | E um cliente chamado "Dr. Bill" 18 | E um blog chamado "Terapia Caro" de propriedade de "Dr. Bill" 19 | 20 | Cenário : o Dr. Bill publica seu próprio blog 21 | Dado que estou logado como Dr. Bill 22 | Quando tento publicar no "Terapia cara" 23 | Então eu deveria ver "Seu artigo foi publicado". 24 | 25 | Cenário : o Dr. Bill tenta publicar no blog de outra pessoa, e falha. 26 | Dado que estou logado como Dr. Bill. 27 | Quando eu tento publicar em "revistas anti-impostos de Greg" 28 | Então eu deveria ver "Ei, esse não é o seu blog!" 29 | 30 | Cenário : Greg publica no blog de um cliente 31 | Dado que estou logado como Greg 32 | Quando eu tento publicar em "Terapia Caro" 33 | Então eu deveria ver "Seu artigo foi publicado". 34 | ``` 35 | 36 | Para uma alternativa menos explícita ao background, verifique os ganchos com Tagged [Hooks](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/05-hooks.md); 37 | 38 | ## Boas práticas para usar Background 39 | 40 | Não use "Background" para configurar o estado complicado, a menos que esse estado seja realmente algo que o cliente precisa saber. 41 | 42 | Por exemplo, se o usuário e o nome do site não importarem para o cliente, você deve usar uma etapa de alto nível, como "Dado que eu estou logado como proprietário do site". 43 | 44 | Mantenha sua seção "Background" curta . 45 | Você está esperando que o usuário realmente se lembre dessas coisas ao ler seus cenários. Se o plano de fundo tiver mais de 4 linhas, você pode mover alguns dos detalhes irrelevantes em etapas de alto nível? Veja Passos de Chamada das Definições de Etapas . 46 | 47 | Faça sua seção "Background" vívida . 48 | Você deve usar nomes coloridos e tentar contar uma história, porque o cérebro humano pode acompanhar as histórias muito melhor do que pode acompanhar nomes como "Usuário A", "Usuário B", "Site 1", e assim por diante. 49 | 50 | Mantenha seus cenários curtos e não tenha muitos. 51 | Se a seção de fundo tiver escorregado na tela, você deve pensar em usar etapas de nível superior ou dividir o arquivo * .features em dois. 52 | 53 | 54 | Vamos para o próximo post [Hooks](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/05-hooks.md); 55 | 56 | ## Referências: 57 | 58 | https://github.com/cucumber/cucumber -------------------------------------------------------------------------------- /tests/Cucumber/05-hooks.md: -------------------------------------------------------------------------------- 1 | # Hooks(Ganchos) 2 | 3 | Cucumber fornece uma série de hooks que nos permitem executar blocos em vários pontos no ciclo de teste de cucumber. Você pode colocá-los no seu support/env.rb arquivo ou em qualquer outro arquivo no support diretório, por exemplo, em um arquivo chamado support/hooks.rb. Não há associação entre onde o hooks é definido e qual cenário / passo é executado, mas você pode usar hooks marcados (veja abaixo) se você quiser mais controle de grão fino. 4 | 5 | Todos os hooks definidos são executados sempre que ocorre o evento relevante. 6 | 7 | ## Scenario hooks(Ganchos de cenário) 8 | 9 | ## Before(Antes) 10 | 11 | Os hooks serão executados antes do primeiro passo de cada cenário. Eles serão executados na mesma ordem em que estão registrados. 12 | 13 | ``` 14 | Before do 15 | # Faça algo antes de cada cenário. 16 | end 17 | ``` 18 | 19 | ``` 20 | Before do |cenário| 21 | # O argumento + argumento + é opcional, mas se você usá-lo, você pode obter o título, 22 | a descrição ou o nome (título + descrição) do cenário que está prestes a ser 23 | executado # . 24 | Rails.logger.debug "Starting scenario: #{scenario.title}" 25 | end 26 | ``` 27 | 28 | ## After(Depois) 29 | 30 | Os hooks serão executados após o último passo de cada cenário, mesmo quando houver etapas falhas, indefinidas, pendentes ou ignoradas. Eles correrão na ordem oposta da qual eles estão registrados. 31 | 32 | ``` 33 | After do |cenário| 34 | # Faça algo depois de cada cenário. 35 | # O argumento + argumento + é opcional, mas 36 | # se você usá-lo, você pode verificar o status com 37 | # o #failed ?, #passed? e # métodos de exceção. 38 | 39 | if scenario.failed? 40 | subject = "[Project X] #{scenario.exception.message}" 41 | send_failure_email(subject) 42 | end 43 | end 44 | ``` 45 | 46 | Aqui é outro exemplo, onde nós saímos no primeiro fracasso (pode ser útil em alguns casos raros como Integração Contínua quando o feedback rápido é importante). 47 | 48 | ``` 49 | After do |s| 50 | # Diga ao Pepino para sair depois que este cenário for concluído - se ele falhar. 51 | Cucumber.wants_to_quit = true if s.failed? 52 | end 53 | ``` 54 | 55 | ## Around(Em torno) 56 | 57 | Os hooks correrão "em torno" de um cenário. Isso pode ser usado para envolver a execução de um cenário em um bloco. O gancho Around ganha um objeto de cenário e um objeto de bloco (Proc). O cenário será executado quando você invoca block. call. 58 | 59 | O exemplo a seguir causará que os cenários marcados com @fast falha se a execução demorar mais de 0,5 segundos: 60 | 61 | ``` 62 | Around('@fast') do |cenario, block| 63 | Timeout.timeout(0.5) do 64 | block.call 65 | end 66 | end 67 | ``` 68 | 69 | Você pode querer dar uma olhada no SystemTimer se desejar mais confiável timeout. 70 | 71 | ## Step hooks(Gancho de passo) 72 | 73 | Aviso: O bloqueio AfterStep não funciona com cenários que tenham backgrounds (cucumber 0.3.11) 74 | 75 | ``` 76 | AfterStep do |scenario| 77 | # Faça algo depois de cada passo. 78 | end 79 | ``` 80 | 81 | ## Tagged hooks(Ganchos marcados) 82 | 83 | Às vezes, você pode querer que um determinado hooks seja executado apenas para determinados cenários. Isto pode ser conseguido através da associação a Before, After, Aroundou AfterStep hooks com uma ou mais tag . Você pode tag OR e AND do mesmo modo que você pode ao executar Cucumber a partir da linha de comando. 84 | Exemplos: 85 | 86 | Para tags OR, passe as tags em uma única seqüência separada por vírgulas: 87 | 88 | ``` 89 | Before('@cucumis, @sativus') do 90 | # Isso só será executado antes dos cenários marcados 91 | # com @cucumis OR @sativus. 92 | end 93 | ``` 94 | 95 | Para tags AND, passe as tags como seqüências de tags separadas: 96 | 97 | ``` 98 | Before('@cucumis', '~@sativus') do 99 | # Isso só será executado antes dos cenários marcados 100 | # com @cucumis E NÃO @sativus. 101 | end 102 | ``` 103 | 104 | Você cria condições de etiqueta complexas usando as tags OR e AND em: 105 | 106 | ``` 107 | Before('@cucumis, @sativus', '@aqua') do 108 | # Isso só será executado antes dos cenários marcados 109 | # com (@cucumis OU @sativus) E @aqua 110 | end 111 | ``` 112 | 113 | Exemplo após passo: 114 | 115 | ``` 116 | AfterStep('@cucumis', '@sativus') do 117 | # Isso só será executado após as etapas dentro de cenários marcados 118 | # com @cucumis AND @sativus. 119 | end 120 | ``` 121 | 122 | Pense duas vezes antes de usar esse recurso, pois o que quer que aconteça nos hooks é invisível para as pessoas que apenas lêem os recursos. Você deve considerar usar o plano de fundo como uma alternativa mais explícita se a configuração for legível por pessoas não-técnicas. 123 | 124 | ## Global hooks(Ganchos globais) 125 | 126 | Se você quiser que algo aconteça uma vez antes de qualquer cenário é executado - basta colocar esse código no nível superior em seu env.rb arquivo (ou qualquer outro arquivo em seu features/support diretório. Use Kernel#at_exit para o desmontagem global. Exemplo: 127 | 128 | ``` 129 | my_heavy_object = HeavyObject.new 130 | my_heavy_object.do_it 131 | 132 | at_exit do 133 | my_heavy_object.undo_it 134 | end 135 | ``` 136 | 137 | Running a Before hook only once (Executando um gancho antes apenas uma vez) 138 | 139 | Se você tiver um hooks, você só deseja executar uma vez, use uma variável global: 140 | 141 | ``` 142 | Before do 143 | $dunit ||= false # tem que definir uma variável antes que possamos fazer referência ao seu its value 144 | return $dunit if $dunit # bail se $ dunit TRUE 145 | step "run the really slow log in method" # caso contrário, faça isso. 146 | $dunit = true # não faça isso novamente. 147 | end 148 | ``` 149 | 150 | ## AfterConfiguration(Após configuração) 151 | 152 | Você também pode fornecer um AfterConfigurationgancho que será executado após o Cucumber ter sido configurado. O bloco que você fornecerá será passado a configuração do cucumber (uma instância de Cucumber::Cli::Configuration). Exemplo: 153 | 154 | ``` 155 | AfterConfiguration do |config| 156 | puts "Features dwell in #{config.feature_dirs}" 157 | end 158 | ``` 159 | 160 | Este hooks será executado apenas uma vez; após o suporte ter sido carregado, mas antes que os recursos sejam carregados. Você pode usar esse hooks para estender o Cucumber, por exemplo, você pode afetar a forma como os recursos são carregados ou registrar formatadores personalizados programaticamente. 161 | 162 | Vamos para o próximo post [Chamando steps dentro de step definitions](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/06-chamando_steps.md); 163 | 164 | ## Referências: 165 | 166 | https://github.com/cucumber/cucumber 167 | 168 | -------------------------------------------------------------------------------- /tests/Cucumber/06-chamando_steps.md: -------------------------------------------------------------------------------- 1 | # Calling Steps from Step Definitions(Chamando Passos das Definições de Etapas) 2 | 3 | É possível chamar etapas de Definições de Etapas : 4 | 5 | ```ruby 6 | # ruby 7 | Dado / ^ o usuário (. *) existe $ / do | name | 8 | # ... 9 | end 10 | 11 | Dado / ^ eu logo como (. *) $ / do | name | 12 | # ... 13 | end 14 | 15 | Quando /^(.*) está logado em $ / do | name | 16 | passo "o usuário # {nome} existe" 17 | etapa "eu logar como # {nome}" 18 | fim 19 | ``` 20 | 21 | A partir da versão 0.4.4 você também pode fazer isso: 22 | 23 | ```ruby 24 | Dado /^(.*) está logado em $ / do | name | 25 | # Look ma, sem citações! 26 | # Mais fácil de fazer "extrair passos de texto simples" refatorações com corte e colar! 27 | step% Q { 28 | Dado o usuário # {nome} existir 29 | Dado eu logar como # {nome} 30 | } 31 | end 32 | ``` 33 | 34 | Invocar etapas de definições de etapas é prático se você tiver várias etapas comuns que deseja executar em vários cenários. - Simplesmente se você quiser tornar seus cenários mais curtos e mais declarativos. Isso permite que você faça isso em um Cenário: 35 | 36 | ``` 37 | # recurso 38 | Cenário: Veja os últimos incidentes 39 | Dado que Linda está logada # Isso, de fato, invocará definições de 2 passos 40 | Quando eu for para a página do incidente 41 | ``` 42 | 43 | Em vez de ter muita repetição: 44 | 45 | ``` 46 | # feature 47 | Cenário: Veja os últimos incidentes 48 | Dado o usuário Linda existe 49 | E eu logo como Linda 50 | Quando eu vou para a página do incidente 51 | ``` 52 | 53 | ## Calling steps with multiline step arguments(Chamando etapas com argumentos de várias etapas) 54 | 55 | Às vezes, você quer chamar um passo que foi projetado para levar os argumentos da etapa Multiline , por exemplo: 56 | 57 | ## Tables(Tabelas) 58 | 59 | ```ruby 60 | # ruby 61 | Dado / ^ um relatório de despesas para (. *) com as seguintes posts: $ / do | date, posts_table | 62 | # A variável posts_table é uma instância de Cucumber :: Ast :: Table 63 | end 64 | ``` 65 | 66 | Isso pode ser facilmente chamado a partir de um passo de texto simples como este: 67 | 68 | ``` 69 | # feature 70 | Dado um relatório de despesas para janeiro de 2009 com as seguintes postagens: 71 | | conta | descrição | quantidade | 72 | | INT-100 | Táxi | 114 | 73 | | CUC-101 | Peeler | 22 | 74 | ``` 75 | 76 | Mas e se você quiser chamar isso de uma definição de passo? Há algumas maneiras de fazer isso: 77 | 78 | ```ruby 79 | # ruby 80 | Dado / Um simples relatório de despesas / 81 | step "um relatório de despesas para janeiro de 2009 com as seguintes postagens:", table (% { 82 | | conta | descrição | montante 83 | | INT-100 | Taxi | 114 84 | | CUC-101 | Peeler | 22 | 85 | }) 86 | end 87 | ``` 88 | 89 | Ou, se você preferir uma abordagem mais programática: 90 | 91 | ```ruby 92 | # ruby 93 | Given / Um simples relatório de despesas / 94 | step "um relatório de despesas para janeiro de 2009 com as seguintes postagens:", table ([ 95 | % w {quantidade da descrição da conta}, 96 | % w {INT-100 Taxi 114}, 97 | % w {CUC -101 Peeler 22} 98 | ]) 99 | fim 100 | ``` 101 | 102 | Você também pode simplesmente receber uma mesa e passá-la para baixo. Esta definição de passo em espanhol passa sua tabela para o inglês: 103 | 104 | ```ruby 105 | # ruby 106 | Então / ^ debo ver los links: $ / do | links_table | 107 | Então "Eu deveria ver os links:", link_table 108 | end 109 | 110 | Então / ^ Eu deveria ver os links: $ / do | links_table | 111 | links_table.hashes.each do | hash | 112 | Então "Eu deveria ver o link # {hash ['link']}" 113 | end 114 | end 115 | ``` 116 | 117 | ## Multiline Strings(Cordas Multilíneas) 118 | 119 | Para chamar um passo que leva uma string de várias linhas, como 120 | 121 | ```ruby 122 | # ruby 123 | Dado / ^ Eu preencho "([^ \"] *) "com $ / do | campo, pystring | 124 | fill_in (campo:: com => pystring) 125 | end 126 | ``` 127 | 128 | a partir de uma definição de passo, passe a string após a etapa: 129 | 130 | ```ruby 131 | # ruby 132 | Dado / ^ existe um documento com conteúdo $ / do | pystring | 133 | step 'Eu vou adicionar um documento' 134 | step 'Eu preencho" ditacontent "com ', pystring 135 | step ' Eu pressiono" Add to repository "' 136 | end 137 | ``` 138 | 139 | Vamos para o próximo post [Esquema do Cenário](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/07-esquema_cenario.md); 140 | 141 | ## Referências: 142 | 143 | https://github.com/cucumber/cucumber -------------------------------------------------------------------------------- /tests/Cucumber/07-esquema_cenario.md: -------------------------------------------------------------------------------- 1 | # Scenario Outlines(Esquema do Cenário) 2 | 3 | Copiar e colar cenários para usar diferentes valores rapidamente torna-se tedioso e repetitivo: 4 | 5 | ``` 6 | Cenário : coma 5 em 12 7 | Dado que existem 12 pepinos 8 | Quando eu como 5 pepinos 9 | Então eu deveria ter 7 pepinos Cenário : comer 5 de 20 Dado que há 20 pepinos 10 | Quando eu comer 5 pepinos 11 | Então eu deveria ter 15 Pepinos 12 | ``` 13 | 14 | Os esquema do cenário nos permitem expressar de forma mais concisa esses exemplos através do uso de um modelo com espaços reservados, usando Esquema do Cenário, Exemplos com tabelas e < > parâmetros delimitados: 15 | 16 | ``` 17 | Esquema do Cenário: Comer 18 | Dado que existem pepinos 19 | Quando eu comer pepinos 20 | Então eu deveria ter Pepinos 21 | 22 | Exemplos : 23 | | Comece | coma | esquerda | 24 | | 12 | 5 | 7 | 25 | | 20 | 5 | 15 | 26 | ``` 27 | 28 | As Esquema do cenário fornecem um modelo que nunca é executado diretamente. Um cenário de cenário é executado uma vez para cada linha na Exemplo seção abaixo dela (sem contar a primeira linha). 29 | 30 | A maneira como isso funciona é através de espaços reservados. Os marcadores de posição devem estar contidos nos < > passos do cenário do cenário. 31 | Por exemplo: 32 | 33 | ``` 34 | Dado 35 | ``` 36 | 37 | Os espaços reservados indicam que, quando a linha Exemplos é executada, eles devem ser substituídos por valores reais da Exemplos tabela. Se um nome de espaço reservado for o mesmo que um título de coluna na Exemplos tabela, esse é o valor que o substituirá. 38 | 39 | Você também pode usar marcadores de posição em argumentos de etapa multilinha. 40 | 41 | IMPORTANTE: Suas definições de etapa nunca terão que corresponder a um espaço reservado. Eles precisarão combinar os valores que irão substituir o marcador de posição. 42 | 43 | Então, ao executar a primeira linha do nosso exemplo: 44 | 45 | ``` 46 | Exemplos : 47 | | Comece | coma | esquerda | 48 | | 12 | 5 | 7 | 49 | ``` 50 | 51 | O cenário que realmente é executado é: 52 | 53 | ``` 54 | Cenário Destaque : comer 55 | Dado que há 12 pepinos # substituídos por 12 56 | Quando eu como 5 pepinos # substituído por 5 57 | Então eu deveria ter 7 pepinos # <à esquerda> substituídos por 7 58 | ``` 59 | 60 | ## Referências: 61 | 62 | https://github.com/cucumber/cucumber -------------------------------------------------------------------------------- /tests/Cucumber/08-tags.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Cucumber/09-data_table.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Cucumber/10-cucumberyml.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Cucumber/comandos_cucumber.md: -------------------------------------------------------------------------------- 1 | # Aqui iremos falar um pouco sobre o Cucumber 2 | 3 | 1. [Introdução a Cucumber](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/01-introducao_cucumber.md); 4 | 2. [Instalação do Cucumber](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/02-instalacao_cucumber.md); 5 | 3. [Comandos Given(Dado) When(Quando) Then(Então) And(E) But(Mas)](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/03-given_when_then_but_and.md); 6 | 4. [Background(Contexto)](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/04-background.md); 7 | 5. [Hooks](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/05-hooks.md); 8 | 6. [Chamando steps(passos) dento de um step definition](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/06-chamando_steps.md); 9 | 7. [Esquema de Cenário](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/07-esquema_cenario.md); 10 | 8. [Esquema de Tags](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/08-tags.md); 11 | 9. [Data Table](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/09-data_table.md); 12 | 10. [Cucumber.yml](https://github.com/brunobatista25/best_archer/blob/master/tests/Cucumber/10-cucumberyml.md); 13 | 14 | 15 | MAIS EM BREVE... -------------------------------------------------------------------------------- /tests/Docker/comandos_docker.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/Docker/comandos_docker.md -------------------------------------------------------------------------------- /tests/Gitlabci/comandos_gitlabci.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Httparty/comandos_httparty.md: -------------------------------------------------------------------------------- 1 | http://watir.com/guides/wysiwyg/ 2 | 3 | ## classe metods 4 | 5 | #base_uri(uri = nil) ⇒ Object 6 | Allows setting a base uri to be used for each request. 7 | #basic_auth(u, p) ⇒ Object 8 | Allows setting basic authentication username and password. 9 | #ciphers(cipher_names) ⇒ Object 10 | Allows setting of SSL ciphers to use. 11 | #connection_adapter(custom_adapter = nil, options = nil) ⇒ Object 12 | Allows setting a custom connection_adapter for the http connections. 13 | #cookies(h = {}) ⇒ Object 14 | #copy(path, options = {}, &block) ⇒ Object 15 | Perform a COPY request to a path. 16 | #debug_output(stream = $stderr) ⇒ Object 17 | Set an output stream for debugging, defaults to $stderr. 18 | #default_params(h = {}) ⇒ Object 19 | Allows setting default parameters to be appended to each request. 20 | #default_timeout(t) ⇒ Object 21 | Allows setting a default timeout for all HTTP calls Timeout is specified in seconds. 22 | #delete(path, options = {}, &block) ⇒ Object 23 | Perform a DELETE request to a path. 24 | #digest_auth(u, p) ⇒ Object 25 | Allows setting digest authentication username and password. 26 | #disable_rails_query_string_format ⇒ Object 27 | Do not send rails style query strings. 28 | #follow_redirects(value = true) ⇒ Object 29 | Proceed to the location header when an HTTP response dictates a redirect. 30 | #format(f = nil) ⇒ Object 31 | Allows setting the format with which to parse. 32 | #get(path, options = {}, &block) ⇒ Object 33 | Allows making a get request to a url. 34 | #head(path, options = {}, &block) ⇒ Object 35 | Perform a HEAD request to a path. 36 | #headers(h = nil) ⇒ Object 37 | Allows setting HTTP headers to be used for each request. 38 | #http_proxy(addr = nil, port = nil, user = nil, pass = nil) ⇒ Object 39 | Allows setting http proxy information to be used. 40 | #logger(logger, level = :info, format = :apache) ⇒ Object 41 | Turns on logging. 42 | #maintain_method_across_redirects(value = true) ⇒ Object 43 | Declare that you wish to maintain the chosen HTTP method across redirects. 44 | #mkcol(path, options = {}, &block) ⇒ Object 45 | Perform a MKCOL request to a path. 46 | #move(path, options = {}, &block) ⇒ Object 47 | Perform a MOVE request to a path. 48 | #no_follow(value = false) ⇒ Object 49 | Declare whether or not to follow redirects. 50 | #open_timeout(t) ⇒ Object 51 | Allows setting a default open_timeout for all HTTP calls in seconds. 52 | #options(path, options = {}, &block) ⇒ Object 53 | Perform an OPTIONS request to a path. 54 | #parser(custom_parser = nil) ⇒ Object 55 | Allows setting a custom parser for the response. 56 | #patch(path, options = {}, &block) ⇒ Object 57 | Perform a PATCH request to a path. 58 | #pem(pem_contents, password = nil) ⇒ Object 59 | Allows setting a PEM file to be used. 60 | #pkcs12(p12_contents, password) ⇒ Object 61 | Allows setting a PKCS12 file to be used. 62 | #post(path, options = {}, &block) ⇒ Object 63 | Allows making a post request to a url. 64 | #put(path, options = {}, &block) ⇒ Object 65 | Perform a PUT request to a path. 66 | #query_string_normalizer(normalizer) {|Hash, String| ... } ⇒ Object 67 | Override the way query strings are normalized. 68 | #raise_on(codes = []) ⇒ Object 69 | Raises HTTParty::ResponseError if response's code matches this statuses. 70 | #read_timeout(t) ⇒ Object 71 | Allows setting a default read_timeout for all HTTP calls in seconds. 72 | #resend_on_redirect(value = true) ⇒ Object 73 | Declare that you wish to resend the full HTTP request across redirects, even on redirects that should logically become GET requests. 74 | #ssl_ca_file(path) ⇒ Object 75 | Allows setting an OpenSSL certificate authority file. 76 | #ssl_ca_path(path) ⇒ Object 77 | Allows setting an OpenSSL certificate authority path (directory). 78 | #ssl_version(version) ⇒ Object 79 | Allows setting of SSL version to use. 80 | #uri_adapter(uri_adapter) ⇒ Object 81 | Allows setting a custom URI adapter. -------------------------------------------------------------------------------- /tests/Jenkins/comandos_jenkins.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/JsonSchema/comandos_json_schema.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Rake/comandos_rake.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Rspec/comandos_rspec.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/01-hello_world.md: -------------------------------------------------------------------------------- 1 | Antes de começar essa aula voçê precisa configurar o ambiente segue abaixo o link para configuração do ambiente: 2 | 3 | 1. [Configuração Ruby](https://github.com/brunobatista25/best_archer/blob/master/tests/ConfiguracaoRuby/configuracao_ruby.md); 4 | 5 | 6 | Depois de ter feito o passo acima. 7 | 8 | No ruby basta criar um arquivo que termine com .rb 9 | 10 | Exemplo: "arquivo.rb" 11 | 12 | Depois insira esses dois comandos nele. 13 | 14 | Depois abra o terminal e digite ruby nome_do_arquivo.rb,que ele irá executar os comandos. 15 | 16 | ```ruby 17 | puts 'Ola mundo!' 18 | puts " #{1 + 2} " 19 | ``` 20 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/02-entrada_e_saida.md: -------------------------------------------------------------------------------- 1 | O comando gets serve para ler coisas que são inseridas no teclado 2 | 3 | O comando puts imprime o resultado na tela 4 | 5 | ```ruby 6 | puts "ola" 7 | puts "Digite seu nome:" 8 | v1 = gets.chomp 9 | puts "O seu nome é " + v1 10 | ``` 11 | 12 | O comando \n - insere uma nova linha ou enter 13 | O comando chomp retira a quebra de linha 14 | 15 | ``` 16 | gets.chomp 17 | ``` 18 | 19 | O comando inspect verifica o que tem dentro da variável que pode estar escondida 20 | 21 | ```ruby 22 | puts "Digite a sua idade?" 23 | v2 = gets.chomp 24 | puts "Sua idade é " + v2.inspect 25 | puts "Sua idade é " + v2 26 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/03-variaveis_e_primitivos.md: -------------------------------------------------------------------------------- 1 | Os tipos Primitivos são o numeros inteiros e reais: 2 | 3 | Tipo de Primitivos: 4 | 5 | Inteiro(sem casa decimal). 6 | ```ruby 7 | 1 8 | 45 9 | 947 10 | ``` 11 | 12 | Reais(com casa decimal(que são separados com ponto). 13 | ```ruby 14 | 8.67 15 | 4.8 16 | ``` 17 | 18 | Obs: 19 | 20 | No Ruby 2.3 21 | 22 | Inteiro era chamado "fixnum" 23 | 24 | No ruby 2.4 25 | 26 | Inteiro e chamado "Integer" 27 | 28 | E também tempos os tipos primitivos que os caracteres e booleano: 29 | 30 | Caracteres/String 31 | ```ruby 32 | 'a' 33 | "#" 34 | "@3d%" 35 | ``` 36 | 37 | Quando tem so uma letra é chamado de Caracteres 38 | 39 | Quando tem vários simbolos é chamado String 40 | 41 | Somar duas letras elas são concatenadas. 42 | 43 | ```ruby 44 | '3' + '1' 45 | '31' 46 | ``` 47 | 48 | O tipo primitivo Booleano: 49 | 50 | true e usado para quando algo for verdadeiro. 51 | 52 | false e usado para quando algo for falso. 53 | 54 | ```ruby 55 | true 56 | false 57 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/04-comentarios.md: -------------------------------------------------------------------------------- 1 | Par fazer um comentário em ruby basta usar o "#" 2 | 3 | para comentar uma linha basta usar o nomeço da linha com o '#' 4 | 5 | Exemplo 6 | 7 | ```ruby 8 | #testando comentário 9 | ``` 10 | 11 | Temos tambem o comentário para várias linhas 12 | com o begin e terminado com o end 13 | 14 | ```ruby 15 | =begin 16 | #testando comentário 17 | =end 18 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/05-string_e_interpolacao.md: -------------------------------------------------------------------------------- 1 | String é tudo aquilo que está dentro de um "" ou '' 2 | 3 | exemplo 4 | 5 | ```ruby 6 | puts "string" 7 | puts 'string' 8 | ``` 9 | 10 | ```ruby 11 | v1 = 'Bruno' 12 | puts "Hello!" + v1 13 | 14 | v2 = "Bruno" 15 | ``` 16 | 17 | Para concatenar apenas e feita por uma variavel que estaja dentro de aspas duplas. 18 | 19 | Para contatenar uma variável e preciso que ela esteja neste formato: 20 | 21 | Começando com hastag e chaves,e dentro da chaves a variável. 22 | 23 | #{variavel} 24 | 25 | Exemplo de interpolação 26 | 27 | ```ruby 28 | este codigo não consegue interpolar devido ter apenas aspas simples. 29 | puts 'Beleza? #{v2}' 30 | 31 | forma correta de interpolar variável 32 | puts "Beleza? #{v2}" 33 | 34 | puts "A soma de 1 + 2 é: #{1 + 2}" 35 | ``` 36 | 37 | Podemos concatenar tambem com o << 38 | 39 | ```ruby 40 | puts "Beleza?" << "Brunao" 41 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/06-coercao.md: -------------------------------------------------------------------------------- 1 | Coerção ou cast 2 | 3 | Serve para transformar uma variável para inteiro,float,string,simbolo ou array 4 | 5 | ```ruby 6 | to_i #Converte a variável inteiro 7 | to_f #Converte a variável float 8 | to_s #Converte a variável para string 9 | to_sym #Converte a variável para simbolo 10 | to_a #Converte a variável para array 11 | ``` 12 | 13 | Exemplo: 14 | 15 | ```ruby 16 | puts "Digite sua idade:" 17 | v1 = gets.chomp 18 | v2 = v1.to_i + 1 19 | puts "Sua idade ano que vem será? #{v2}" 20 | 21 | #tentando interporlar sem converter 22 | puts "Digite sua idade:" 23 | v1 = gets.chomp.to_i 24 | v2 = v1 + 1 25 | puts "Sua idade ano que vem será? #{v2}" 26 | ``` 27 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/07-operadores_aritimeticos.md: -------------------------------------------------------------------------------- 1 | Operadores 2 | + adição 3 | - subtração 4 | * multiplicação 5 | / divisão 6 | % módulo(pega o resto da divisão) 7 | ** exponenciação 8 | 9 | Exemplos: 10 | 11 | ```ruby 12 | puts "A soma de 1 + 2 é: #{1 + 2}" 13 | ``` 14 | 15 | ```ruby 16 | puts "A subtração de 2 + 1 é: #{2 - 1}" 17 | ``` 18 | 19 | ```ruby 20 | puts "A multiplicação de 1 * 2 é: #{1 * 2}" 21 | ``` 22 | 23 | ```ruby 24 | puts "A divisão de 10 / 2 é: #{10 / 2}" 25 | ``` 26 | 27 | ```ruby 28 | puts "A resto da exponenciação de 10 % 2 é: #{10 % 2}" 29 | ``` 30 | 31 | ```ruby 32 | puts "A exponenciação de 2 ** 2 é: #{2 ** 2}" 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/08-operadores_relacionais.md: -------------------------------------------------------------------------------- 1 | # Operadores Relacionais 2 | 3 | ``` 4 | > maior 5 | < menor 6 | >= maior ou igual 7 | <= menor ou igual 8 | == igual 9 | != diferente 10 | <=> spaceShip(o resultado disso sempre da: -1, 0 e 1. 11 | -1(quando o elemento da direita e maior que a esquerda) , 12 | 0(quando os elementos são iguais) 13 | 1(quando o elemento da esquerda e maior que da direita)) 14 | ``` 15 | 16 | ```ruby 17 | puts "2 é maior que 1? #{2 > 1}" 18 | puts "1 é maior que 2? #{1 > 2}" 19 | ``` 20 | 21 | ```ruby 22 | puts "1 é menor que 2? #{1 < 2}" 23 | puts "2 é menor que 1? #{2 < 1}" 24 | ``` 25 | 26 | ```ruby 27 | puts "2 é maior ou igual que 1? #{2 >= 1}" 28 | puts "1 é maior ou igual que 2? #{1 >= 2}" 29 | ``` 30 | 31 | ```ruby 32 | puts "1 é menor ou igual que 2? #{1 <= 2}" 33 | puts "2 é menor ou igual que 1? #{2 <= 1}" 34 | ``` 35 | 36 | ```ruby 37 | puts "2 é igual que 2? #{2 == 2}" 38 | puts "2 é igual que 3? #{2 == 3}" 39 | ``` 40 | 41 | ```ruby 42 | puts "2 é diferente que 1? #{2 != 1}" 43 | puts "2 é diferente que 2? #{2 != 2}" 44 | ``` 45 | 46 | ```ruby 47 | puts "1 e maior,menor ou igual que 2? #{1 <=> 2}" 48 | puts "2 e maior,menor ou igual que 2? #{2 <=> 2}" 49 | puts "2 e maior,menor ou igual que 1? #{2 <=> 1}" 50 | ``` 51 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/09-operador_de_atribuicao.md: -------------------------------------------------------------------------------- 1 | Operadores de atribuicao 2 | Quando queremos atribuir um valor a mais na mesma variavel e usado desde jeito: 3 | 4 | ```ruby 5 | a = a + 1 6 | ``` 7 | Pra isso temos varias formas de se resolver. 8 | 9 | ```ruby 10 | a = a + 4 atribui um valor a uma variavel 11 | a += 4 equivale a = a + 4 12 | a -= 4 equivale a = a - 4 13 | a *= 4 equivale a = a * 4 14 | a %= 4 equivale a = a % 4 15 | a /= 4 equivale a = a / 4 16 | a **= 4 equivale a = a ** 4 17 | ``` 18 | 19 | ```ruby 20 | a = 2 21 | a += 4 # a = a + 4 22 | puts a 23 | ``` 24 | 25 | ```ruby 26 | b = 4 27 | b -= 2 # a = a - 2 28 | puts b 29 | ``` 30 | 31 | ```ruby 32 | c = 4 33 | c /= 2 # a = a / 2 34 | puts c 35 | ``` 36 | 37 | ```ruby 38 | d = 4 39 | d *= 4 # a = a * 4 40 | puts c 41 | ``` 42 | 43 | ```ruby 44 | e = 2 45 | e **= 4 # a = a ** 4 46 | puts e 47 | ``` 48 | 49 | ```ruby 50 | f = 10 51 | f %= 5 # a = a % 5 52 | puts f 53 | ``` 54 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/10-estruturas_condicionais.md: -------------------------------------------------------------------------------- 1 | # Estruturas condicionais 2 | 3 | ## if elsif else: 4 | 5 | IF(se) a condição for atendida faça algo, ELSIF (senão, se) outra condição for atendida faça algo, ELSE (senão) faça algo, END (fim da condição). 6 | 7 | ## Unless: 8 | 9 | O controle unless é como a estrutura if, só que negativa, ao contrário do if, basicamente o uso é o mesmo do if só que ao contrário, apenas isso. 10 | 11 | ## Case when 12 | 13 | Avalia uma lista de condições e retorna uma das várias expressões de resultado possíveis, a expressão CASE tem dois formatos: CASE simples compara uma expressão com um conjunto de expressões simples para determinar o resultado e a expressão CASE que avalia um conjunto de expressões booleanas para determinar o resultado. Ambos os formatos suportam um argumento ELSE opcional. 14 | 15 | ```ruby 16 | puts "Digite um número" 17 | v1 = gets.chomp.to_i 18 | 19 | #se a variavel v1 for maior que 10 20 | if v1 > 10 21 | #entao imprime 22 | puts "O valor digitado é maior do que 10" 23 | #se nao 24 | else 25 | puts "O valor digitado é menor ou igual 10" 26 | end 27 | 28 | if v1 > 10 then#então 29 | puts "O valor digitado é maior do que 10" 30 | else 31 | puts "O valor digitado é menor ou igual 10" 32 | end 33 | ``` 34 | 35 | ```ruby 36 | puts "Digite um número" 37 | v1 = gets.chomp.to_i 38 | 39 | if v1 > 10 then#então 40 | puts "O valor digitado é maior do que 10" 41 | elsif v1 >= 5 42 | puts "O valor digitado é maior ou igual que 5(entre 5 e 10)" 43 | else 44 | puts "O valor digitado é menor 5" 45 | end 46 | ``` 47 | 48 | 49 | 50 | E o inverso do if ele faz a negação 51 | Exemplo: 52 | A menos que v1 seja menor que 10 53 | 54 | ```ruby 55 | puts "Digite um número" 56 | v1 = gets.chomp.to_i 57 | 58 | #A menos que v1 seja menor que 10 59 | unless v1 > 10 60 | puts "O valor é menor que 10" 61 | else 62 | puts "O valor e maior que 10" 63 | end 64 | ``` 65 | 66 | ```ruby 67 | puts "Digite um número de 1 a 5" 68 | v1 = gets.chomp.to_i 69 | 70 | case v1 71 | when 1 72 | puts "Você escolheu o número 1" 73 | when 2 74 | puts "Você escolheu o número 2" 75 | when 3 76 | puts "Você escolheu o número 3" 77 | when 4 78 | puts "Você escolheu o número 4" 79 | when 5 80 | puts "Você escolheu o número 5" 81 | else 82 | puts "Opção Inválida!" 83 | end 84 | ``` 85 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/11-operadores_logicos.md: -------------------------------------------------------------------------------- 1 | # Operadores logicos 2 | 3 | Os operadores lógicos são usados ​​para comparar duas expressões e retornar um resultado booleano (verdadeiro ou falso). Esses operadores juntam essas expressões retornando verdadeiro ou falso. 4 | 5 | ```ruby 6 | && equivale a e 7 | || equilvale a ou 8 | ! equivale a negacao 9 | ``` 10 | 11 | ```ruby 12 | Operador O que faz? Exemplo Método? 13 | and ou && #Se ambas condições forem verdadeiras, então é retornado true (a && b) é verdadeiro Não 14 | or ou || #Se algumas das condições forem diferente de zero, o retorno é true (a or b) é verdadeiro Não 15 | not ou ! #Inverte o estado da lógica do operando !(a && b) é falso Não 16 | ``` 17 | 18 | ```ruby 19 | v1 = 34 20 | v2 = 56 21 | v3 = 2 22 | v4 = 7 23 | ``` 24 | 25 | ```ruby 26 | if (v1 < v2) && (v3 < v4) 27 | puts "condicao atendida nos dois casos" 28 | else 29 | puts "condicao não atendida nos dois casos" 30 | end 31 | ``` 32 | # ou 33 | 34 | ```ruby 35 | if (v1 < v2) and (v3 < v4) 36 | puts "condicao atendida nos dois casos" 37 | else 38 | puts "condicao não atendida nos dois casos" 39 | end 40 | ``` 41 | 42 | ```ruby 43 | # pelo uma condicao sendo atendida 44 | if (v1 < v2) || (v3 > v4) 45 | puts "condicao atendida nos dois casos" 46 | else 47 | puts "condicao não atendida nos dois casos" 48 | end 49 | ``` 50 | #ou 51 | 52 | ```ruby 53 | if (v1 < v2) or (v3 > v4) 54 | puts "condicao atendida pelo menos em um casos" 55 | else 56 | puts "condicao não atendida nos dois casos" 57 | end 58 | ``` 59 | 60 | ```ruby 61 | #esta negando os dois casos 62 | if !(v3 < v4) 63 | puts "negacao atendida" 64 | else 65 | puts "negacao nao atendida" 66 | end 67 | ``` 68 | 69 | ```ruby 70 | #esta negando os dois casos 71 | if !(v3 > v4) 72 | puts "negacao atendida" 73 | else 74 | puts "negacao nao atendida" 75 | end 76 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/12-estrutura_de_repeticao.md: -------------------------------------------------------------------------------- 1 | # Estrutura de Repetição 2 | 3 | 4 | For -- O laço for é uma estrutura de repetição muito utilizada, É muito útil quando se sabe de antemão quantas vezes a repetição deverá ser executada. 5 | 6 | While -- Enquanto o teste for verdadeiro vai fazer o bloco de repetição. 7 | 8 | Until -- enquanto for falso não vai fazer nada. 9 | 10 | Loop -- Um loopirá executar qualquer código dentro do bloco (mais uma vez, isso é apenas entre o {}ou do ... end) até que intervir manualmente com Ctrl + cou inserir uma breakdeclaração dentro do bloco, que irá forçar o loop para parar e a execução continuará após o loop. 11 | 12 | ``` 13 | a = 0 14 | for i in 0..10 do 15 | a = a + 1 16 | end 17 | 18 | puts a 19 | ``` 20 | 21 | ``` 22 | i = 1 23 | 24 | while i <= 50 25 | puts "bruno - #{i}" 26 | i += 1 27 | end 28 | ``` 29 | 30 | ``` 31 | #aqui o 1 está com o valor de 50 32 | # i == 50 33 | until i <= 1 34 | puts "sou falso - #{i}" 35 | i -= 1 36 | end 37 | ``` 38 | 39 | ``` 40 | loop do 41 | a = gets.chomp 42 | if a = sair do 43 | exit 44 | end 45 | end 46 | ``` 47 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/13-vetores_e_arrays.md: -------------------------------------------------------------------------------- 1 | #Vetores e Arrays 2 | 3 | ## Vetor (array uni-dimensional) 4 | É uma variável que armazena várias variáveis do mesmo tipo. No problema apresentado anteriormente, nós podemos utilizar um vetor de 50 posições para armazenar os nomes dos 50 alunos. 5 | 6 | ## Matriz (array multi-dimensional) 7 | É um vetor de vetores. No nosso problema, imagine uma matriz para armazenar as 4 notas de cada um dos 50 alunos. Ou seja, um vetor de 50 posições, e em cada posição do vetor, há outro vetor com 4 posições. Isso é uma matriz. 8 | 9 | Cada item do vetor (ou matriz) é acessado por um número chamado de índice. 10 | 11 | No ruby usamos os bracket(conchetes). 12 | 13 | ``` 14 | [] 15 | ``` 16 | 17 | Exemplosde iniciar um array: 18 | 19 | ``` 20 | v = Array.new 21 | v1 = [] 22 | puts v1 23 | v2 = [1,2,3,4,5] 24 | puts v2 25 | v3 = [1,2,3,4,5] 26 | puts v3[0] 27 | v4 = Array.new(5,'a') # estou dizendo que quero 5 variaveis a nas 5 posições do array 28 | puts v4 29 | v5 = %w(Rio de janeiro) # pra cada espaco ele cria uma outra posicao no array 30 | puts v5 31 | ``` 32 | 33 | atribuindo no array 34 | 35 | ``` 36 | v6 = [1,2,3,4,5] 37 | v6 << [6] 38 | puts v6 39 | ``` 40 | O vetor sempre começa na posição 0, ou seja o valor 1 está na posição 0 do array 41 | 42 | ``` 43 | [ 44 | 1, #posição 0 45 | 2, #posição 1 46 | 3, #posição 2 47 | 4, #posição 3 48 | 5 #posição 4 49 | ] 50 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/14-hashes.md: -------------------------------------------------------------------------------- 1 | #Hashes (dicionários) 2 | 3 | Hashes (também conhecidos como arrays associativos, mapas ou dicionários) são similares aos arrays a medida que são coleções indexadas de referências a objetos. No entanto, enquanto o o array é indexado por inteiros (semelhante a um índice remissivo), o hash pode ser indexado com objetos de qualquer tipo: strings, expressões regulares e assim por diante. Quando você armazena um valor em um hash, você na verdade fornece dois objetos – o índice (normalmente chamado de chave) e o valor desse índice. É possível recuperar os valores utilizando o índice do hash. Os valores do hash, assim como os índices, podem ser objetos de qualquer tipo. 4 | 5 | O exemplo abaixo cria um hash com literais (strings): uma lista de pares chave => valor entre 6 | 7 | ```ruby 8 | ruby codigo_exemplo.rb 9 | h = {'cachorro' => 'canino', 'gato' => 'felino', 10 | 'burro' => 'asinino', 12 => 'dodezino'} 11 | puts h.length # 4 12 | puts h['cachorro'] # 'canino' 13 | puts h 14 | puts h[12] 15 | ``` 16 | 17 | A saída do código acima é: 18 | 19 | ```ruby 20 | >ruby codigo_exemplo.rb 21 | 4 22 | canino 23 | {"cachorro"=>"canino", "gato"=>"felino", 24 | "burro"=>"asinino", 12=>"dodezino"} 25 | dodezino 26 | >Exit code: 0 27 | ``` 28 | 29 | Caso o programa apresentado no exemplo seja executado no Ruby 1.8 a saída será um pouco diferente. Em todos exemplos estamos utilizando o Ruby 1.9, no qual o hash é apresentado de forma ordenada e igual a sua declaração. Já no Ruby 1.8 a ordenação do hash é diferente da declarada 30 | 31 | Comparados com arrays, os hashes têm uma vantagem significativa: eles podem usar qualquer objeto como índice. 32 | 33 | Hashes têm um valor padrão. Tal valor é retornado após uma tentativa de acesso a uma chave não existente. Por padrão este valor é nil. 34 | 35 | A classe Hash tem muitos métodos e você pode consultá-los aqui (em inglês). 36 | 37 | Usando Símbolos como chaves do Hash 38 | Ao invés, de utilizar uma string como chave, de preferência pelo uso de um símbolo. Veja o exemplo a seguir no programa codigo_exemplo.rb. 39 | 40 | ```ruby 41 | 1 # codigo_exemplo.rb 42 | 2 pessoa = Hash.new 43 | 3 pessoa[:apelido] = 'GuruIndiano' 44 | 4 pessoa[:idioma] = 'Marata' 45 | 5 pessoa[:sobrenome] = 'Talim' 46 | 6 puts pessoa[:sobrenome] # Talim 47 | ``` 48 | 49 | Outro exemplo p0411symbolhash.rb. 50 | 51 | ```ruby 52 | 1 # codigo_exemplo.rb 53 | 2 h = {:apelido => 'GuruIndiano', :idioma => 'Marata', :sobrenome => 'Talim'} 54 | 3 puts h 55 | ``` 56 | 57 | A saída do exemplo acima é: 58 | 59 | ```ruby 60 | 1 {:apelido=>"GuruIndiano", :idioma=>"Marata", :sobrenome=>"Talim"} 61 | ``` 62 | 63 | Outra maneira de fazer a mesma coisa é mostrada no programa p0412symbolhash.rb. 64 | 65 | ```ruby 66 | 1 # codigo_exemplo.rb 67 | 2 h = {apelido: 'GuruIndiano', idioma: 'Marata', sobrenome: 'Talim'} 68 | 3 puts h 69 | ``` 70 | 71 | A saída é: 72 | 73 | ```ruby 74 | 1 {:apelido=>"GuruIndiano", :idioma=>"Marata", :sobrenome=>"Talim"} 75 | ``` 76 | 77 | Ou seja, exatamente o mesmo que ocorreu na execução do programa codigo_exemplo.rb. 78 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/15-simbolos.md: -------------------------------------------------------------------------------- 1 | #Símbolo 2 | 3 | Um símbolo (Symbol) se parece com um nome de variável mas é prefixado com dois pontos (:). Exemplos: :action, :line_items. Você não precisa pré-declarar um símbolo e garante-se que eles sejam únicos. Não há necessidade de se atribuir algum tipo de valor para um símbolo – Ruby cuida disso para você. A linguagem também garante que não importa onde apareça em seu programa, um símbolo particular terá sempre o mesmo valor. 4 | 5 | Alternativamente, você pode considerar que os dois pontos significam “coisa chamada”. Assim, :id é “a coisa chamada id”. Você pode pensar também em :id significando o nome da variável id, e o id (sem os dois pontos) significando o valor da variável. 6 | 7 | Um símbolo é o objeto Ruby mais básico que você pode criar. Ele é apenas um nome e um ID interno. Símbolos são úteis porque um dado nome de símbolo se refere ao mesmo objeto através de um programa Ruby. Símbolos são mais eficientes que strings. Duas strings com o mesmo conteúdo são dois objetos diferentes, mas para qualquer nome existe apenas um objeto Symbol. Isso pode economizar tempo e memória. 8 | 9 | Veja o exemplo exemplo.rb abaixo: 10 | 11 | ```ruby 12 | 1 # exemplo.rb 13 | 2 # use o object_id da classe Object 14 | 3 # ele retorna um inteiro identificador para um objeto 15 | 4 puts "string".object_id 16 | 5 puts "string".object_id 17 | 6 puts :symbol.object_id 18 | 7 puts :symbol.object_id 19 | ``` 20 | 21 | A saída quando rodei o programa no meu PC foi: 22 | 23 | ```ruby 24 | 1 >ruby exemplo.rb 25 | 2 21066960 26 | 3 21066930 27 | 4 132178 28 | 5 132178 29 | 6 >Exit code: 0 30 | ``` 31 | 32 | Então, quando usamos uma string e quando usamos um símbolo? 33 | 34 | Se o conteúdo (a sequência de caracteres) do objeto é importante, use uma string. 35 | Se a identidade do objeto é importante, use um símbolo. 36 | 37 | Ruby usa símbolos e mantem uma tabela de símbolos para armazená-los. Símbolos são nomes – nome de variáveis de instância, nomes de métodos, nomes de classes. Então, se existe um método chamado control_movie, existe automaticamente um símbolo :control_movie. Ruby é interpretado, então ele mantem sua tabela de símbolos acessível o tempo todo. Você pode encontrar o que está nela a qualquer momento chamando Symbol.all_symbols. 38 | 39 | Um objeto do tipo símbolo é criado prefixando-se um operador, string, variável, constante, método, classe ou módulo como dois pontos. O objeto símbolo será único para cada diferente nome mas não se referirá particularmente a instância do nome, durante a execução do programa. Então, se Fred é uma constante em um contexto, um método em outro e uma classe em um terceiro, o símbolo :Fred será o mesmo objeto em todos os três contextos. 40 | 41 | Isso pode ser ilustrado por esse simples programa – exemplo.rb: 42 | 43 | ```ruby 44 | 1 # exemplo.rb 45 | 2 class Test 46 | 3 puts :Test.object_id.to_s 47 | 4 def test 48 | 5 puts :test.object_id.to_s 49 | 6 @test = 10 50 | 7 puts :test.object_id.to_s 51 | 8 end 52 | 9 end 53 | 10 t = Test.new 54 | 11 t.test 55 | ``` 56 | 57 | A saída que obtive quando rodei o programa no meu PC foi: 58 | 59 | ```ruby 60 | 1 >ruby exemplo.rb 61 | 2 116458 62 | 3 79218 63 | 4 79218 64 | 5 >Exit code: 0 65 | ``` 66 | 67 | Aqui temos outro exemplo – exemplo.rb: 68 | 69 | ```ruby 70 | 1 # exemplo.rb 71 | 2 sabe_ruby = :sim 72 | 3 if sabe_ruby == :sim 73 | 4 puts 'Voce eh um rubista' 74 | 5 else 75 | 6 puts 'Aprenda Ruby' 76 | 7 end 77 | ``` 78 | 79 | A saída é: 80 | 81 | ```ruby 82 | 1 >ruby exemplo.rb 83 | 2 Voce eh um rubista 84 | 3 >Exit code: 0 85 | ``` 86 | 87 | No exemplo, :sim é um símbolo. Símbolos não contêm valores ou objetos como as variáveis Ao invés disso, eles são usados como um nome consistente no código. Por exemplo, no código mostrado anteriormente você poderia facilmente substituir o símbolo por 88 | uma string como no exemplo exemplo.rb: 89 | 90 | ```ruby 91 | 1 # exemplo.rb 92 | 2 sabe_ruby = 'sim' 93 | 3 if sabe_ruby == 'sim' 94 | 4 puts 'Voce eh um rubista' 95 | 5 else 96 | 6 puts 'Aprenda Ruby' 97 | 7 end 98 | ``` 99 | 100 | Isto tem o mesmo resultado, mas não é mais eficiente. Nesse exemplo, cada menção do ‘sim’ cria um novo objeto armazenado separadamente em memória, enquanto símbolos são valores com referência única inicializados apenas uma vez. No primeiro exemplo, 101 | apenas :sim existe, enquanto no segundo exemplo você têm duas strings ‘sim’ e ‘sim’ ocupando espaço na memória. 102 | 103 | Podemos também transformar uma string em um símbolo e vice-versa: 104 | 105 | ```ruby 106 | 1 puts "string".to_sym.class # Symbol 107 | 2 puts :symbol.to_s.class # String 108 | ``` 109 | 110 | Símbolos são particularmente úteis quando se cria hashes e você quer distinguir chaves e valores. Veja o tópico usando símbolos como chaves hash para exemplos práticos. 111 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/16-iterador_each.md: -------------------------------------------------------------------------------- 1 | # Interador each 2 | 3 | Each Iterator: Eu gosto bastante do iterador each. É bem simples e expressivo. Para uma lista de valores, vamos iterar passando 1 por 1 dentro do bloco do iterador. Dentro dele podemos usar a variável definida. 4 | 5 | ```ruby 6 | [1, 2, 3, 4, 5].each do |num| 7 | puts num 8 | end 9 | ``` 10 | 11 | Você, talvez, esteja se perguntando o por que de usar o iterator each ao invés de usar for. A grande diferença é que o iterador each mantém a variável apenas dentro do seu escopo. Enquanto o for. mantém a variável viva fora do seu escopo. Vamos fazer um teste: 12 | 13 | ```ruby 14 | # for vs each 15 | 16 | # for looping 17 | for num in 1...5 18 | puts num 19 | end 20 | 21 | puts num # => 5 22 | 23 | # each iterator 24 | [1, 2, 3, 4, 5].each do |num| 25 | puts num 26 | end 27 | 28 | puts num # => undefined local variable or method `n' for main:Object (NameError) 29 | ``` 30 | 31 | A variável num continuará “viva” após o bloco de iteração do loop for. Enquanto para o iterador each essa variável não existirá mais fora de seu escopo. 32 | -------------------------------------------------------------------------------- /tests/Ruby/RubyBasico/17-operadores_de_intervalo.md: -------------------------------------------------------------------------------- 1 | # Operadores de intervalo 2 | 3 | Determina um alcance do ponto de partida até o ponto final inclusivo 4 | 5 | Com (..) três pontos ele vai até o penúltimo elemento. 6 | 7 | ```ruby 8 | (1...5) 9 | #vai de 1 a 4 10 | ``` 11 | 12 | Com (..) dois pontos ele vai até o último elemento 13 | 14 | ```ruby 15 | (1..5) 16 | #vai de 1 a 5 17 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/01-classe.md: -------------------------------------------------------------------------------- 1 | # Classe 2 | 3 | Uma classe é um gabarito para a definição de objetos. Através da definição de uma classe, descreve-se que propriedades -- ou atributos -- o objeto terá. 4 | 5 | Além da especificação de atributos, a definição de uma classe descreve também qual o comportamento de objetos da classe, ou seja, que funcionalidades podem ser aplicadas a objetos da classe. Essas funcionalidades são descritas através de métodos. Um método nada mais é que o equivalente a um procedimento ou função, com a restrição que ele manipula apenas suas variáveis locais e os atributos que foram definidos para a classe. 6 | 7 | A especificação de uma classe é composta por três regiões: 8 | 9 | # Nome da classe 10 | Um identificador para a classe, que permite referenciá-la posteriormente -- por exemplo, no momento da criação de um objeto. 11 | 12 | # Atributos 13 | 14 | O conjunto de propriedades da classe. Para cada propriedade, especifica-se: 15 | 16 | nome: um identificador para o atributo. 17 | tipo: o tipo do atributo (inteiro, real, caráter, etc.) 18 | valor_default: opcionalmente, pode-se especificar um valor inicial para o atributo. 19 | visibilidade: opcionalmente, pode-se especificar o quão acessível é um atributo de um objeto a partir de outros objetos. Valores possíveis são: 20 | 21 | (privativo), nenhuma visibilidade externa; 22 | 23 | (público), visibilidade externa total; 24 | 25 | (protegido), visibilidade externa limitada. 26 | 27 | # Métodos 28 | 29 | O conjunto de funcionalidades da classe. Para cada método, especifica-se sua assinatura, composta por: 30 | 31 | nome: um identificador para o método. 32 | 33 | tipo: quando o método tem um valor de retorno, o tipo desse valor. 34 | 35 | lista de argumentos: quando o método recebe parâmetros para sua execução, o tipo e um identificador para cada parâmetro. 36 | visibilidade: como para atributos, define o quão visível é um método a partir de objetos de outros classes. 37 | 38 | As técnicas de programação orientada a objetos recomendam que a estrutura de um objeto e a implementação de seus métodos devem ser tão privativos como possível. Normalmente, os atributos de um objeto não devem ser visíveis externamente. Da mesma forma, de um método deve ser suficiente conhecer apenas sua especificação, sem necessidade de saber detalhes de como a funcionalidade que ele executa é implementada. 39 | 40 | # Criando uma classe 41 | 42 | O nome da classe sempre começa com letra maiúscula 43 | 44 | ```ruby 45 | class NomeDaClasse 46 | #CORPO DA CLASSE 47 | end 48 | ``` 49 | 50 | # Como instância uma classe 51 | 52 | ```ruby 53 | objto1 = NomeDaClasse.new 54 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/02-metodos.md: -------------------------------------------------------------------------------- 1 | # Método 2 | 3 | def é uma palavra chave do Ruby para a definição (criação) de métodos, que podem, claro, receber parâmetros: 4 | 5 | ```ruby 6 | def pessoa.vai(lugar) 7 | puts "indo para " + lugar 8 | end 9 | ``` 10 | Mas, e o retorno de um método? Como funciona? Para diminuir o excesso de código que as linguagens costumam introduzir (chamado de ruído sintático), o Ruby optou por retornar o resultado da execução da última instrução executada no método. O exemplo a seguir mostra um método que devolve uma String: 11 | 12 | ```ruby 13 | def pessoa.vai(lugar) 14 | "indo para " + lugar 15 | end 16 | ``` 17 | 18 | Para visualizar esse retorno funcionando, podemos acessar o método e imprimir o retorno do mesmo: 19 | 20 | ```ruby 21 | puts pessoa.vai("casa") 22 | ``` 23 | 24 | Podemos ainda refatorar o nosso método para usar interpolação: 25 | 26 | ```ruby 27 | def pessoa.vai(lugar) 28 | "indo para #{lugar}" 29 | end 30 | ``` 31 | 32 | Para receber vários argumentos em um método, basta separá-los por vírgula: 33 | 34 | ```ruby 35 | def pessoa.troca(roupa, lugar) 36 | "trocando de #{roupa} no #{lugar}" 37 | end 38 | ``` 39 | 40 | A invocação desses métodos é feita da maneira tradicional: 41 | 42 | ```ruby 43 | pessoa.troca('camiseta', 'banheiro') 44 | ``` 45 | 46 | Alguns podem até ter um valor padrão, fazendo com que sejam opcionais: 47 | 48 | ```ruby 49 | def pessoa.troca(roupa, lugar='banheiro') 50 | "trocando de #{roupa} no #{lugar}" 51 | end 52 | ``` 53 | 54 | # invocação sem o parametro: 55 | 56 | ```ruby 57 | pessoa.troca("camiseta") 58 | ``` 59 | 60 | # invocação com o parametro: 61 | 62 | ```ruby 63 | pessoa.troca("camiseta", "sala") 64 | ``` -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/03-definindo_atributos.md: -------------------------------------------------------------------------------- 1 | # Atributos 2 | 3 | Atributos, também conhecidos como variáveis de instância, em Ruby são sempre privados e começam com @. Não há como alterá-los de fora da classe; apenas os métodos de um objeto podem alterar os seus atributos (encapsulamento!). 4 | 5 | ```ruby 6 | class Pessoa 7 | def muda_nome(novo_nome) 8 | @nome = novo_nome 9 | end 10 | 11 | def diz_nome 12 | "meu nome é #{@nome}" 13 | end 14 | end 15 | 16 | p = Pessoa.new 17 | p.muda_nome "João" 18 | p.diz_nome 19 | 20 | # => "João" 21 | ``` 22 | 23 | Podemos fazer com que algum código seja executado na criação de um objeto. Para isso, todo objeto pode ter um método especial, chamado de initialize: 24 | 25 | ```ruby 26 | class Pessoa 27 | def initialize 28 | puts "Criando nova Pessoa" 29 | end 30 | end 31 | Pessoa.new 32 | # => "Criando nova Pessoa" 33 | ``` 34 | 35 | Os initializers são métodos privados (não podem ser chamados de fora da classe) e podem receber parâmetros. Veremos mais sobre métodos privados adiante. 36 | 37 | ```ruby 38 | class Pessoa 39 | def initialize(nome) 40 | @nome = nome 41 | end 42 | end 43 | 44 | joao = Pessoa.new("João") 45 | ``` 46 | 47 | Métodos acessores e modificadores são muito comuns e dão a ideia de propriedades. Existe uma convenção para a definição destes métodos, que a maioria dos desenvolvedores Ruby segue (assim como Java tem a convenção para getters e setters): 48 | 49 | ```ruby 50 | class Pessoa 51 | def nome # acessor 52 | @nome 53 | end 54 | 55 | def nome=(novo_nome) 56 | @nome = novo_nome 57 | end 58 | end 59 | 60 | pessoa = Pessoa.new 61 | pessoa.nome=("José") 62 | puts pessoa.nome 63 | # => "José" 64 | ``` 65 | -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/04-initialize.md: -------------------------------------------------------------------------------- 1 | # Inicializando objetos 2 | 3 | No momento do nascimento 4 | 5 | Vamos começar de novo e definir uma nova classe. 6 | 7 | Lembre-se de como dissemos que os objetos podem ser pensados ​​como duas coisas: sabem coisas e podem fazer coisas . 8 | 9 | Vamos definir uma aula Person. As pessoas, obviamente, também sabem coisas e podem fazer coisas. 10 | 11 | Veja como definir uma classe brilhante, nova e vazia Person: 12 | 13 | ```ruby 14 | class Person 15 | end 16 | ``` 17 | 18 | Novamente, essa não é uma classe muito útil, mas podemos instanciá-la, e criar uma instância real, concreta pessoa (objeto) a partir dele: 19 | 20 | ```ruby 21 | p Person.new 22 | ``` 23 | 24 | Agora, antes de adicionar qualquer comportamento (métodos) à nossa classe, queremos poder dar alguns dados iniciais: no nosso caso, queremos que a pessoa conheça seu próprio nome. 25 | 26 | Nós podemos fazer isso assim: 27 | 28 | ```ruby 29 | class Person 30 | def initialize(name) 31 | end 32 | end 33 | ``` 34 | 35 | Você vê que nós adicionamos um método chamado initializepara a classe, e esse método aceita um único argumento, chamado name. No momento, esse método ainda está vazio. Vamos adicionar um pouco de código a ele um pouco. 36 | 37 | O bit importante para aprender para você é: o método initializeé um método especial com um significado especial em Ruby: 38 | 39 | Sempre que você chamar o método newem uma classe, como dentro Person.new, a classe criará uma nova instância de si mesma. Então, internamente, chamará o método initializeno novo objeto. Ao fazê-lo, simplesmente passará todos os argumentos que você passou new para o método initialize. 40 | 41 | Então, podemos agora criar uma nova instância de pessoa chamando ... 42 | 43 | ```ruby 44 | Person.new("Ada") 45 | ``` 46 | 47 | ... e a string "Ada"será transmitida ao nosso initializemétodo e acabará sendo atribuída à variável local name. 48 | 49 | O método especial initializeé chamado sob o capô quando o objeto foi criado pelo método de classe new. 50 | 51 | Obviamente, nosso initializemétodo não faz nada com a String passada, ainda assim. Está certo. Chegaremos a isso no próximo capítulo. 52 | 53 | Para recapitular, quando você invoca newa classe Persone passa a string "Ada", o método newcriará uma nova instância da classe e ligará initializepara ela, passando a mesma lista de argumentos, que em nosso caso é a única string "Ada". 54 | 55 | Quando criamos uma nova instância de uma classe pela forma de chamar o método new nessa classe, também dizemos que "instanciamos" esse objeto: Ao chamar, Person.newcriamos um novo objeto de pessoa. 56 | -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/05-herança.md: -------------------------------------------------------------------------------- 1 | # O que é Herança ? 2 | 3 | A Herança é um dos pilares da programação orientada a objetos e é uma técnica comumente utilizada quando se quer reaproveitar código já existente e também descrever uma relação entre classes de modo que determinadas classes possam herdar atributos e métodos de uma classe de nível superior. 4 | 5 | Essas classes podem ser descritas como: Classe Pai, Superclasse ou Classe Base, que é a classe que contém as características que serão herdadas pelas classes de nível mais baixo na hierarquia. 6 | 7 | E existem também as descritas: Classes Filhas, Derivadas ou Subclasses, que são justamente as classes que herdam as características de sua classe base e também podem conter suas próprias característas, ou ainda refinar (especializar para o seu contexto) uma determinada característica herdada de sua classe base. 8 | 9 | A Herança descreve uma relação é do tipo entre as classes que estão nessa hierarquia. Conforme o exemplo abaixo: 10 | 11 | ```ruby 12 | class Calendar 13 | attr_reader :start_date, :end_date 14 | 15 | def initialize; end 16 | 17 | def date_range 18 | raise 'Must implement!' 19 | end 20 | end 21 | 22 | class WeeklyCalendar < Calendar 23 | def date_range 24 | base_date.beginning_of_week(:sunday)..base_date.end_of_week(:sunday) 25 | end 26 | end 27 | 28 | class MonthlyCalendar < Calendar 29 | def date_range 30 | base_date.beginning_of_month.beginning_of_week(:sunday)..base_date.end_of_month.end_of_week(:sunday) 31 | end 32 | end 33 | ``` 34 | 35 | Na hierarquia proposta acima é possível verificar a superclasse Calendar e analisar que as classes WeeklyCalendar e MonthlyCalendar possuem uma relação é do tipo com relação a superclasse Calendar, afinal de contas essas classes representam um tipo de calendário, porém mais especializadas. 36 | 37 | Dessa forma o uso da Herança pode ser aplicado como técnica para descrever a relação entre as classes e também aplicar o reuso de código. Importante notar também que apesar de utilizar a Herança para reaproveitar determinados trechos de código, cada tipo de calendário também pode especializar as características que forem necessárias para seu contexto, no caso do exemplo cada calendário implementa seu próprio método date_range. 38 | 39 | Quais os principais problemas com uso de Herança ? 40 | Se a Herança faz tudo isso que foi dito acima, por quais motivos ela pode ser ruim para o desenvolvimento ? 41 | 42 | Um dos principais problemas encontrados ao fazer uso massivo de Herança é o alto acoplamento e o baixo encapsulamento de informações de cada classe. 43 | 44 | Quanto maior o acoplamento mais difícil é alterar as classes, realizar modificações em uma classe base sem que essa modificação se propague para suas classes filhas, ou em casos mais graves, um erro escrito em uma classe irá se propagar para as demais dentro da hierarquia. E o baixo encapsulamento se da ao fato que as classes envolvidas podem acabar tendo muito conhecimento do estado interno de outras classes. 45 | 46 | Outro problema relacionado ao auto acoplamento criado pela Herança é que torna difícil que comportamentos sejam adicionados ou removidos em tempo de execução, ou então fazer objetos terem outros comportamentos para diferentes contextos em diferentes momentos dentro do software. 47 | 48 | Nem sempre uma subclasse precisa herdar todos os atributos ou métodos de sua superclasse, nesse caso há uma quebra do Princípio de Segregação de Interface, que dita que classes não devem implementar aquilo que não irão utilizar apenas para satisfazer a Herança. 49 | 50 | Por fim, a Herança pode parecer uma boa alternativa em primeiro momento porém com o passar do tempo e o crescimento do software as classes começam a crescer e ganhar diferentes comportamentos, ficando cada vez mais diferentes até chegar a um ponto que a relação entre as classes antes ditas como é do tipo X estarem mais com cara de compartilham algumas funcionalidades com Y, desse modo não fazendo mais sentido o uso de Herança. 51 | 52 | REFERÊNCIAS: 53 | 54 | http://shipit.resultadosdigitais.com.br/blog/composicao-e-heranca-no-ruby/ -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula10.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula11.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula12.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula13.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula14.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula6.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula7.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula8.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/RubyOrientadoObjeto/aula9.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Ruby/comandos_ruby.md: -------------------------------------------------------------------------------- 1 | # Aqui iremos falar um pouco sobre o Ruby básico 2 | 3 | # Primeira parte é comandos básicos de Ruby. 4 | 5 | 1. [Hello World](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/01-hello_world.md); 6 | 2. [Entradas e Saídas](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/02-entrada_e_saida.md); 7 | 3. [Variáveis e Primitivos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/03-variaveis_e_primitivos.md); 8 | 4. [Comentários](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/04-comentarios.md); 9 | 5. [String e Interpolação](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/05-string_e_interpolacao.md); 10 | 6. [Coersão ou conversões](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/06-coercao.md); 11 | 7. [Operadores Aritimeticos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/07-operadores_aritimeticos.md); 12 | 8. [Operadores Relacionais](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/08-operadores_relacionais.md); 13 | 9. [Operadores de Atribuição](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/09-operador_de_atribuicao.md); 14 | 10. [Estruturas Condicionais](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/10-estruturas_condicionais.md); 15 | 11. [Operadores Lógicos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/11-operadores_logicos.md); 16 | 12. [Estrutura de Repetição](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/12-estrutura_de_repeticao.md); 17 | 13. [Vetores e Arrays](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/13-vetores_e_arrays.md); 18 | 14. [Hashes](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/14-hashes.md); 19 | 15. [Simbolos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/15-simbolos.md); 20 | 16. [Iterador Each](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/16-iterador_each.md); 21 | 17. [Operadores de Intervalo](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyBasico/17-operadores_de_intervalo.md); 22 | 23 | # Segunda parte é sobre linguagem Orientado a Objeto com Ruby. 24 | 25 | 1. [Classe](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/01-classe.md); 26 | 2. [Definir Metódos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/02-metodos.md); 27 | 3. [Definindo Atributos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/03-definindo_atributos.md); 28 | 4. [Construtores](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/04-initialize.md); 29 | 5. [Herança](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/05-herança.md); 30 | 6. [Overriding](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula6.md); 31 | 7. [Super](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula7.md); 32 | 8. [Self](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula8.md); 33 | 9. [Metódos instanciais vs metódos de classe](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula9.md); 34 | 10. [Constantes e classes constantes](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula10.md); 35 | 11. [Módulos](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula11.md); 36 | 12. [Módulos - parte II](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula12.md); 37 | 13. [Mixins](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula13.md); 38 | 14. [Polimorfismo duck typing](https://github.com/brunobatista25/best_archer/blob/master/tests/Ruby/RubyOrientadoObjeto/aula14.md); 39 | -------------------------------------------------------------------------------- /tests/SeleniumWebdriver/comandos_selenium_webdriver.md: -------------------------------------------------------------------------------- 1 | https://seleniumhq.github.io/selenium/docs/api/rb/ -------------------------------------------------------------------------------- /tests/SitePrism/01-introducao.md: -------------------------------------------------------------------------------- 1 | # Introdução 2 | 3 | # SitePrism 4 | 5 | Uma DSL de Modelo de Page Object para o Capybara 6 | 7 | O SitePrism oferece uma DSL simples, limpa e semântica para descrever seu site usando o padrão Modelo de Page Object, para uso com Capybara em testes de aceitação automatizados. 8 | 9 | Encontre a documentação bonita aqui: http://rdoc.info/gems/site_prism/frames 10 | 11 | **Vamos para o próximo post** [Instalando o SitePrism](https://github.com/brunobatista25/best_archer/blob/master/tests/Capybara/02-instalando_siteprism.md); -------------------------------------------------------------------------------- /tests/SitePrism/02-instalando_siteprism.md: -------------------------------------------------------------------------------- 1 | # Instalando o SitePrism 2 | 3 | # Instalar 4 | 5 | ```ruby 6 | gem install site_prism 7 | ``` 8 | 9 | # No arquivo Gemfile 10 | 11 | ```ruby 12 | source 'http://rubygems.org' 13 | 14 | gem 'capybara', '<3.3' 15 | gem 'cucumber' 16 | gem 'selenium-webdriver', '~>3.4' 17 | gem 'rspec' 18 | gem 'site_prism', '2.15.1' 19 | ``` 20 | 21 | # Usando SitePrism com Cucumber 22 | 23 | ```ruby 24 | require 'capybara' 25 | require 'capybara/cucumber' 26 | require 'selenium-webdriver' 27 | require 'site_prism' 28 | ``` 29 | 30 | # Usando SitePrism com Rspec 31 | 32 | ```ruby 33 | require 'capybara' 34 | require 'capybara/rspec' 35 | require 'selenium-webdriver' 36 | require 'site_prism' 37 | ``` 38 | 39 | # Criando um Page Objects 40 | 41 | 42 | O Modelo de Objeto de Página é um padrão de automação de teste que visa criar uma abstração da interface de usuário do seu site que pode ser usada em testes. A maneira mais comum de fazer isso é modelar cada página como uma classe e, em seguida, usar instâncias dessas classes em seus testes. 43 | 44 | Se uma classe representa uma página, então cada elemento da página é representado por um método que, quando chamado, retorna uma referência àquele elemento que pode ser acionado (clicado, definido como valor de texto) ou consultado (está habilitado? / visível?). 45 | 46 | O SitePrism é baseado nesse conceito, mas vai além, como você verá abaixo, também permitindo a modelagem de seções repetidas que aparecem em várias páginas, ou muitas vezes em uma página usando o conceito de seções. 47 | 48 | E para utilizar os métodos do SitePrism basta herdar da classe SitePrism::Page 49 | 50 | ```ruby 51 | class Home < SitePrism::Page 52 | # corpo da classe 53 | end 54 | ``` 55 | 56 | **Vamos para o próximo post** [Setando Url](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/03-setando_urls.md); -------------------------------------------------------------------------------- /tests/SitePrism/03-setando_urls.md: -------------------------------------------------------------------------------- 1 | # Setando urls 2 | 3 | Uma página geralmente tem um URL. Se você quiser navegar até uma página, precisará definir seu URL. Veja como: 4 | 5 | ```ruby 6 | class Home < SitePrism::Page 7 | set_url 'http://www.google.com' 8 | end 9 | ``` 10 | 11 | Se você tiver definido o app_host de Capybara, poderá definir o URL da seguinte maneira: 12 | 13 | ```ruby 14 | class Home < SitePrism::Page 15 | set_url '/home.htm' 16 | end 17 | ``` 18 | 19 | Tenha em atenção que a definição de um URL é opcional. Basta definir um URL para poder navegar diretamente para essa página. Faz sentido definir o URL para um modelo de página de uma página inicial ou uma página de login, mas provavelmente não é uma página de resultados de pesquisa. 20 | -------------------------------------------------------------------------------- /tests/SitePrism/04-elementos.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/05-lista_de_elementos.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/06-ajax.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/07-sessoes.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/08-iframe.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/09-melhorando_pageobjects.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/SitePrism/comandos_siteprism.md: -------------------------------------------------------------------------------- 1 | # SitePrism 2 | 3 | 1. [Introdução](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/01-introducao.md); 4 | 2. [Instalando SitePrism](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/02-instalando_siteprism.md); 5 | 3. [Acessando páginas/url](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/03-setando_urls.md); 6 | 4. [Trabalhando com elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/04-elementos.md); 7 | 5. [Lista de elementos](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/05-lista_de_elementos.md); 8 | 6. [Trabalhando com ajax](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/06-ajax.md); 9 | 7. [Sessōes](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/07-sessoes.md); 10 | 8. [Iframe](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/08-iframe.md); 11 | 9. [Melhorando o page objects](https://github.com/brunobatista25/best_archer/blob/master/tests/SitePrism/09-melhorando_pageobjects.md); 12 | 13 | MAIS EM BREVE... -------------------------------------------------------------------------------- /tests/Travisci/comandos_travis.md: -------------------------------------------------------------------------------- 1 | EM BREVE... -------------------------------------------------------------------------------- /tests/Watir/comandos_watir.md: -------------------------------------------------------------------------------- 1 | http://watir.com/guides/wysiwyg/ 2 | 3 | ##Installing Ruby 4 | 5 | Introduction 6 | In order to run Ruby code you need to install a Ruby interpreter. 7 | 8 | Installing a Ruby interpreter for Windows is straightforward, but for Mac and Linux it is slightly more complicated. The default Ruby interpreters normally supplied on Mac and Linux are not adequate for running Watir and related Ruby technologies without making significant alterations to them. 9 | 10 | There are different options for properly maintaining a Ruby interpreter, but we have chosen rbenv as the most suitable Ruby interpreter for Mac and chruby for Linux. 11 | 12 | Note that RVM is an acceptable (if more complicated) way to maintain a Ruby interpreter if you prefer to use it, but if you choose to use rbenv or chruby, be sure to uninstall RVM completely. 13 | 14 | Windows 15 | Download and install the latest version from rubyinstaller 16 | Mac 17 | Hold down the Command key and press the spacebar to open Spotlight search Type Terminal and hit enter 18 | 19 | Install XCode command-line tools 20 | 21 | Copy and paste this into the terminal and hit enter: 22 | 23 | xcode-select --install 24 | Install HomeBrew 25 | 26 | Copy and paste this into the terminal and hit enter: 27 | 28 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 29 | Install rbenv 30 | 31 | Copy and paste this into the terminal: 32 | 33 | brew install rbenv 34 | rbenv init 35 | touch ~/.bash_profile 36 | echo 'eval "$(rbenv init -)"' >> ~/.bash_profile 37 | source ~/.bash_profile 38 | Copy and paste this into the terminal: 39 | 40 | rbenv install 2.5.1 41 | rbenv local 2.5.1 42 | Linux 43 | Install git Copy and paste this into the terminal: 44 | 45 | sudo apt-get install git 46 | Install ruby-install Copy and paste this into the terminal: 47 | 48 | wget -O ruby-install-0.6.0.tar.gz https://github.com/postmodern/ruby-install/archive/v0.6.0.tar.gz 49 | tar -xzvf ruby-install-0.6.0.tar.gz 50 | cd ruby-install-0.6.0/ 51 | sudo make install 52 | ruby-install ruby 2.5.1 53 | Install chruby Copy and paste this into the terminal: 54 | 55 | cd ../ 56 | wget -O chruby-0.3.9.tar.gz https://github.com/postmodern/chruby/archive/v0.3.9.tar.gz 57 | tar -xzvf chruby-0.3.9.tar.gz 58 | cd chruby-0.3.9/ 59 | sudo make install 60 | sudo ./scripts/setup.sh 61 | xed ~/.bash_profile 62 | Copy and paste this into the bash_profile file that opened in TextEdit: 63 | 64 | source /usr/local/share/chruby/chruby.sh 65 | source /usr/local/share/chruby/auto.sh 66 | Save file and Close TextEdit 67 | 68 | Copy and paste this into the terminal and hit enter: 69 | 70 | source ~/.bash_profile 71 | chruby 2.5.1 72 | -------------------------------------------------------------------------------- 73 | 74 | ##Installing Watir 75 | 76 | Once you have installed Ruby, installing and using Watir is easy. 77 | 78 | From the command line, install the gem, which Ruby’s way of packaging code: 79 | 80 | gem install watir 81 | Now you can try it out by opening up an Interactive Ruby (irb) session. 82 | 83 | If you’re using Mac OS X open up Terminal and type irb, then hit enter. 84 | If you’re using Linux, open up a shell and type irb and hit enter. 85 | If you’re using Windows, open Interactive Ruby. 86 | Now you only need to require the gem to start using it. 87 | 88 | -------------------------------------------------------------------------------- 89 | ##Automation Pipeline 90 | 91 | Watir is a user focused way to test your websites. It mostly uses Selenium for browser automation, but it provides many more high level features that make it easy to write stable, maintainable tests. 92 | 93 | The typical flow of information looks like this: 94 | 95 | Test Runner –> 96 | Test code –> 97 | PageObject code –> 98 | Watir library–> 99 | Selenium library –> 100 | Selenium Server(s) (optional) –> 101 | Browser Driver –> 102 | Browser 103 | 104 | Test Runner. In Ruby this can be MiniTest, RSpec or Cucumber. Most Watir users use RSpec by default, but Cucumber is popular for teams that are working in a Behavior Driven Development environment. 105 | 106 | Test Code. Whether Cucumber Steps or RSpec “it” blocks, the code here should be focused on succinctly representing the business requirement for the test. This is the higher level “what” code that references other objects (like page objects) for the actual implementation. Ruby is more readable than most languages, so name page objects and methods well and a quick skim will allow to the purpose of the test to be easily understood. 107 | 108 | Page Object. This is where the implementation (“how”) code belongs. Page objects can represent an entire page, a modal, or a subset of a page (like a sidebar or a footer). Page objects are typically comprised of two things, the elements with their applicable locators, and the methods that represent the actions that a user can take on the page. Most of this code will be references to Watir objects. 109 | 110 | Watir Code. Watir is designed for “Test Automation.” It takes the code in a page object and translates it into the series of applicable Selenium and JavaScript calls to accomplish the desired functionality. Watir attempts to understand the intention of the code in a test suite and tries to follow a “Do What I Mean” philosophy to accomplish it. Continue reading through the documentation to see how Watir makes writing tests fun and easy. 111 | 112 | Selenium Code. Selenium is designed for “Browser Automation.” It takes the higher focuses on the specific low level actions that can be taken on a browser. It implements a small number of locators and takes a “Do What I Say” approach. It translates idiomatic Ruby code into serialized json blobs to send along for further processing. 113 | 114 | Selenium Server. This isn’t necessary when driving browsers on the same computer as the code. To drive browsers on a remote computer, though, the commands need to be sent to one or more intermediary servers. The Selenium server can be set to act in a standalone mode, or can be set up as a grid with a server acting as a “hub” on one computer, and a server acting as a “node” on another computer. 115 | 116 | Browser Drivers. Because of the progress on the W3C WebDriver Specification, each major browser vendor (Google, Microsoft, Apple, and Mozilla) has committed to implementing their own driver for their respective browser. The driver is an executable file that lives on the same machine as the browser that is being automated. Read the Drivers documentation to see how to download and store the driver so that Selenium can find and use it. The driver accepts the standardized information from Selenium code and translates it into code needed by the particular browser to take the action specified. 117 | 118 | Browser. The browser of your choice executes each command sent by the driver, and sends the results or errors back down this path to the test code. 119 | -------------------------------------------------------------------------- 120 | ##Drivers 121 | 122 | As described in the Automation Pipeline document, a driver must be present on the same machine as the browser you are automating. 123 | 124 | If you are running locally, you can use the webdrivers gem to automatically ensure that the latest driver is downloaded, and placed in a location where Selenium can access it. 125 | 126 | Otherwise, you can download the drivers for the browser of your choice: 127 | 128 | Google Chrome: chromedriver 129 | Mozilla Firefox: geckodriver 130 | Microsoft Edge: Microsoft WebDriver 131 | Microsoft Internet Explorer: IEDriver 132 | Apple Safari: safaridriver (no download needed, it’s pre-installed if you have Safari 10) 133 | For all browsers except for Safari, you then need to move the driver onto your PATH. This can be especially tricky in Windows. 134 | 135 | Alternately, you can avoid dealing with drivers entirely and use an online service provider to manage everything for you. 136 | 137 | Sauce Labs 138 | Browser Stack 139 | 140 | ============================================================================== 141 | 142 | ##Starting a Session 143 | 144 | Opening a Browser 145 | Once you’ve installed Watir, and your desired drivers, and have an open irb session, you can try out opening a browser with: 146 | 147 | require 'watir' 148 | Watir::Browser.new 149 | By default Watir will open a Chrome Browser. 150 | 151 | To open other browsers: 152 | 153 | Watir::Browser.new :firefox 154 | Watir::Browser.new :internet_explorer 155 | Watir::Browser.new :edge 156 | Watir::Browser.new :safari 157 | To open a browser on a remote machine, specify the url: 158 | 159 | Watir::Browser.new :firefox, url: "http://#{the_grid_url}:4444/wd/hub" 160 | There are many settings that can be customized on each browsers: 161 | 162 | Chrome 163 | Firefox 164 | Internet Explorer 165 | Safari 166 | Edge 167 | 168 | ------------------------------------------------------------------------------ 169 | #navegadores 170 | 171 | ##Chrome 172 | 173 | ChromeDriver 174 | To use Chrome, ensure you’re using the appropriate driver 175 | 176 | Starting Chrome 177 | Chrome is the default, so you don’t even have to specify it unless you need to add capabilities. 178 | 179 | b = Watir::Browser.new 180 | b = Watir::Browser.new :chrome, opts 181 | Headless 182 | Chrome has a new headless feature that can be accessed directly with: 183 | 184 | b = Watir::Browser.new :chrome, headless: true 185 | It is still under active development so not all features work yet (alerts, window switching, etc) 186 | 187 | Chrome Options 188 | The options hash can be created with the following parameters: 189 | 190 | :args - an Array of command-line arguments to use when starting Chrome 191 | :binary - a String representing the Path to the Chrome Browser executable to use 192 | :prefs - a Hash with each entry consisting of the name of the preference and its value 193 | :extensions - an Array of Strings listing the paths to (.crx) Chrome extensions to install on startup 194 | :options - a Hash for raw options 195 | :emulation - A Hash for raw emulation options 196 | Preferences 197 | Information on configuring preferences can be found here 198 | 199 | prefs = { 200 | download: { 201 | prompt_for_download: false, 202 | default_directory: '/path/to/dir' 203 | } 204 | } 205 | 206 | b = Watir::Browser.new :chrome, options: {prefs: prefs} 207 | Switches 208 | See the full list of switches here 209 | 210 | args = ['--ignore-certificate-errors', '--disable-popup-blocking', '--disable-translate'] 211 | b = Watir::Browser.new :chrome, options: {args: args} 212 | Raw Options 213 | See the full list of options here 214 | 215 | b = Watir::Browser.new :chrome, options: {options: {detach: true}} 216 | Using chrome on Heroku 217 | You can drive the chrome browser on heroku with a cedar-14 stack. Check out this sample repo for more information on how to do this: https://github.com/jormon/minimal-chrome-on-heroku-xvfb 218 | 219 | You can also run using a headless chrome on the heroku-16 stack. Here’s an example of that working: https://github.com/jormon/minimal-chrome-on-heroku 220 | 221 | ##Firefox 222 | 223 | GeckoDriver 224 | To use Firefox, ensure you’re using the appropriate driver Geckodriver is attempting to be 100% compliant with the soon to be released W3C WebDriver Specification, so it is not yet feature complete. It is recommended that you use the latest browser version available to have the most complete feature set. 225 | 226 | Starting Firefox 227 | b = Watir::Browser.new :firefox 228 | Firefox Options 229 | All options are explained on the geckodriver page 230 | 231 | :args - an Array of command-line arguments to use when starting Firefox 232 | :binary - a String representing the Path to the Firefox Browser executable to use 233 | :profile - an encoded profile string or Firefox::Profile instance 234 | :log_level - the String or Symbol representing the desired log level for geckodriver 235 | :prefs - a Hash with each entry consisting of the key of the preference and its value 236 | Firefox Profiles 237 | You can specify an existing profile to use, such as your ‘default’ profile: 238 | 239 | b = Watir::Browser.new :firefox, profile: 'default' 240 | You can also create a new Firefox profile each test run using any of the options that you can configure in the about:config pane of Firefox 241 | 242 | For example: 243 | 244 | profile = Selenium::WebDriver::Firefox::Profile.new 245 | profile['browser.download.dir'] = '/tmp/webdriver-downloads' 246 | profile['browser.download.folderList'] = 2 247 | profile['browser.helperApps.neverAsk.saveToDisk'] = 'application/pdf' 248 | 249 | b = Watir::Browser.new :firefox, profile: profile 250 | 251 | ##Internet Explorer 252 | 253 | IEDriverServer 254 | To use Internet Explorer, ensure you’re using the appropriate driver. Note that for technical reasons it is recommended to always use the 32 bit version of the driver, regardless of your operating system. 255 | 256 | Starting IE 257 | b = Watir::Browser.new :ie 258 | Configuring IE 259 | Internet Explorer is Windows only and only works if you ensure that Protected Mode settings for each zone are set to the same value. Additional set up suggestions can be found here 260 | 261 | Internet Explorer Options 262 | Watir uses your standard IE settings and config, so you can manually adjust IE to how you want it before running your tests, and it will pick up these settings. 263 | 264 | If you want to customize it in your code here are valid options: 265 | 266 | :args 267 | :browser_attach_timeout 268 | :element_scroll_behavior 269 | :full_page_screenshot 270 | :ensure_clean_session 271 | :file_upload_dialog_timeout 272 | :force_create_process_api 273 | :force_shell_windows_api 274 | :ignore_protected_mode_settings 275 | :ignore_zoom_level 276 | :initial_browser_url 277 | :native_events 278 | :persistent_hover 279 | :require_window_focus 280 | :use_per_process_proxy 281 | :validate_cookie_document_type 282 | args = ["--log-level=DEBUG", "--log-file=/foo"] 283 | Watir::Browser.new :ie, options: {args: args} 284 | Last Updated: August 03, 2018 285 | 286 | ##Safari 287 | 288 | SafariDriver 289 | To use Safari, ensure you’re using the appropriate driver 290 | 291 | safaridriver requires using Safari 10 on either El Capitan or Sierra. 292 | 293 | Apple’s safari driver is still under active development, so there are a number of things that aren’t implemented relative to what is available on other browsers. 294 | 295 | Since the driver that ships with MacOS Sierra does not get updated very often, it is recommended that you download and use the Safari Technology Preview. Note that this is only an option on MacOS. 296 | 297 | Before using safaridriver, turn on the Developer Menu by opening Safari preferences from the Menu Bar, going to the Advanced tab, and ensuring that the Show Develop menu in menu bar checkbox is checked. 298 | 299 | Enable Remote Automation by selecting “Allow Remote Automation” in the Develop Menu in the Menu Bar. 300 | 301 | Authorize safaridriver to launch the webdriverd service which hosts the local web server. To permit this, run /usr/bin/safaridriver once manually and complete the authentication prompt. 302 | 303 | Starting Safari 304 | b = Watir::Browser.new :safari, technology_preview: true 305 | 306 | ##Microsoft Edge 307 | 308 | Microsoft WebDriver 309 | To use Edge, ensure you’re using the appropriate driver 310 | 311 | Microsoft’s WebDriver is still under active development, so there are a number of things that aren’t implemented relative to what is available on other browsers. 312 | 313 | If you are using a Windows 10 Insider Edition, ensure that your driver version matches your Windows Build number 314 | 315 | Starting Edge 316 | b = Watir::Browser.new :edge 317 | -------------------------------------------------------------------------- 318 | ##working elements 319 | 320 | ##Web Elements 321 | 322 | Watir automatically generates classes and methods for all HTML5.1 and SVG2 supported elements and their associated attributes. These classes are encapsulated to give easier access to their specific attributes, making it easier to locate them, and providing custom features unique to them. 323 | 324 | Here are some basic examples for interacting with elements: 325 | 326 | Text Fields 327 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 328 | t = b.text_field id: 'entry_1000000' 329 | t.exists? 330 | t.set 'your name' 331 | t.value 332 | Select Lists – Combos 333 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 334 | s = b.select_list id: 'entry_1000001' 335 | s.select 'Ruby' 336 | s.selected_options 337 | Radios 338 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 339 | r = b.radio value: 'A gem' 340 | r.exists? 341 | r.set 342 | r.set? 343 | Checkboxes 344 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 345 | c = b.checkbox value: '1.9.2' 346 | c.exists? 347 | c.set 348 | c.set? 349 | Buttons 350 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 351 | btn = b.button value: 'Submit' 352 | btn.exists? 353 | btn.click 354 | Links 355 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 356 | l = b.link text: 'Google Forms' 357 | l.exists? 358 | l.click 359 | Divs & Spans 360 | b = Watir::Browser.start 'bit.ly/watir-webdriver-demo' 361 | d = b.div class: 'ss-form-desc ss-no-ignore-whitespace' 362 | d.exists? 363 | d.text 364 | s = b.span class: 'powered-by-text' 365 | s.exists? 366 | s.text 367 | WYSIWYG Editors 368 | See: WYSIWYG Editors page 369 | 370 | ##Locating Elements 371 | 372 | One of the most important features of Watir is the many varied ways it allows users to locate elements. The Watir location API is designed to be easily read and understood by users (humans). Elements are located by creating a Selector Hash, which Watir translates into the potentially complicated information the driver needs to know to identify the element. 373 | 374 | The special cases will be highlighted below, but Watir Locators: 375 | 376 | Accept String values for exact matching 377 | Accept RegExp values for partial matching 378 | Can be mixed with any other Watir Locator 379 | Can be used to find the first matching element, or all matching elements as part of a collection 380 | Firstly, like Selenium, Watir supports the full power of directly using :css & :xpath selectors. When either of these are used, they must be the only one provided in the Selector Hash. Watir’s goal, however, is to minimize the need to rely on these powerful locators. XPath in particular can be difficult to read and can be easy to write in a brittle fashion, so Watir encourages the approach of “No More XPath!” 381 | 382 | Additionally, it is worth noting that there are two locators defined in the WebDriver specification that Watir does not directly support because it provides the same functionality by alternate means. 383 | These are :link_text and :partial_link_text. With Watir you can locate any element by its text, not just links, and Watir already supports partial matches for all of its locators with Regular Expressions. 384 | 385 | Standard Watir Locators 386 | ID 387 | browser.div(id: "header") 388 | browser.div(id: /header/) 389 | Name 390 | browser.text_field(name: 'new_user_email') 391 | browser.text_field(name: /new_user_email/) 392 | Tag Name 393 | # while this works: 394 | browser.element(tag_name: 'div') 395 | 396 | # it is highly recommended to leverage this locator by using the element's associated method: 397 | browser.div 398 | Class Name 399 | # This is for locating with a single class only 400 | browser.text_field(class: 'name') 401 | browser.text_field(class: /name/) 402 | Text 403 | # evaluates what is in the DOM, not what a user can see on the page 404 | browser.button(text: "Button 2") 405 | browser.button(text: /Button/) 406 | Visible Text 407 | # attempts to evaluate based on what a user can see on the page 408 | browser.button(visible_text: "Button 2") 409 | browser.button(visible_text: /Button/) 410 | Data Attributes 411 | browser.p(data_type: "ruby-library") 412 | browser.p(data_type: /ruby-library/) 413 | Aria Attributes 414 | browser.p(aria_label: "ruby-library") 415 | browser.p(aria_label: /ruby-library/) 416 | Valid or Custom Attributes 417 | browser.link(href: 'non_control_elements.html') 418 | browser.link(href: /non_control_elements.html/) 419 | browser.div(custom_attribute: "foo") 420 | browser.div(custom_attribute: /foo/) 421 | Label 422 | # locate based on the value of the associated label element (not attribute) 423 | browser.text_field(label: 'With text')) 424 | browser.text_field(label: /With text/)) 425 | Index 426 | this can not be used to locate an element collection 427 | when combined with other locators, index is the last filter to be applied) 428 | browser.div(index: 2) 429 | Presence/Absence/Multiple Classes 430 | this takes an Array of String or RegExp values 431 | browser.text_field(class: ['order', 'should', 'matter', 'not']) 432 | browser.text_field(class: ['this', '!notthis']) 433 | Presence/Absence Attributes 434 | this takes a Boolean value 435 | browser.div(data_bar: false) 436 | browser.div(data_foo: true) 437 | Visible 438 | this takes a Boolean value 439 | browser.div(visible: true) 440 | browser.div(visible: false) 441 | Adjacent Nodes 442 | these are not locators in the Selector Hash 443 | these are methods that accept a Selector Hash 444 | anchor_element.parent(selectors) 445 | 446 | anchor_element.previous_sibling(selectors) 447 | anchor_element.following_sibling(selectors) 448 | anchor_element.siblings(selectors) 449 | 450 | anchor_element.child(selectors) 451 | anchor_element.children(selectors) 452 | Implementation Details 453 | Most of the time Watir can translate the Selector Hash into a single XPath expression to quickly identify the element. You can get a sense for what this looks like by checking out our sample app XPathify. Instances where this can not be done include when the usage of :visible, :visible_text or :index locators, or (sometimes) when there are Regular Expressions in the locator values. In that case Watir locates potentially matching elements and iterates over them to provide the requested result. 454 | 455 | #Frames 456 | 457 | Think of an IFrame as a page of HTML inside of another page of HTML. They will look like this, with a src attribute that includes the inserted html: 458 | 459 | 460 |

Iframes

461 | 462 | 463 | 464 | By default the browser driver only looks for elements in the top level browsing context. If an element exists inside of an iframe, it must be told to look there. Browser Context switching is handled for you in Watir. The only requirement is that when defining an element, it must include the full address to that element including a reference to any iframes it is nested inside. Recognize that it is possilbe for iframes to be nested inside of iframes. 465 | 466 | b.iframe(id: 'outside').iframe(id: 'inside').div.text 467 | b.iframe(id: 'second').text_field.set 'foo" 468 | b.iframe(id: 'outside').button.click 469 | As of Watir 6.9, if an element can not be located, Watir will check to see if the page has iframes and will advise the user to check to see if the element is inside of an IFrame. 470 | ------------------------------------------------------------------------------- 471 | ##Advanced Interactions 472 | 473 | ##Waiting 474 | 475 | Properly synchronizing your code with the state of the browser has long been the biggest issue testers face when testing a dynamic website. 476 | 477 | Sleeps 478 | It is often discussed that hard coding #sleep is a bad practice. Besides being an indication that your test suite doesn’t have sufficient maturity, there are specific technical frustrations that come with hard coding sleeps. The biggest issue is that you are having to balance the concern of how long is long enough with having an additional and typically unnecessary set of 30 second sleeps scattered everywhere throughout your code. 479 | 480 | Selenium Waits - Implicit & Explicit 481 | Selenium has two approaches to synchronization. The first is “implicit wait.” Presumably this feature was inspired by the early versions of Watir which did a better job of automatically waiting for elements. Using implicit waits means telling the driver to apply a global value for how long to wait when attempting to locate an element if it can’t find the element. The idea behind implicit waits is good, but there are two main issues with this form of implementation, so Watir does not recommend and does not provide direct access for setting them. 482 | 483 | The wait happens during the locate instead of when trying to act on the element. This makes it impossible to immediately query the state of an element before it is there. 484 | Implicit waits by themselves will not be sufficient to handle all of the synchronization issues in your code. The combination of delegating waiting responsibilities to the driver and leveraging polling in the code (explicit waits) can cause weirdness that is difficult to debug. 485 | The second and recommended approach to waiting in Selenium is to use explicit waits. This retains responsibility for synchronization with your code. In this approach your code will continuously check to see if the supplied condition is met, and continue with the next piece of the code when so. Watir waiting approaches all leverage this idea of polling for the desired output from a supplied condition 486 | 487 | When Present and When Enabled 488 | Prior to Watir 6.0, the best way to ensure that the code waited for the browser to be ready was to insert a #when_present or #when_enabled method before the action. 489 | 490 | browser.text_field(title: 'Search').when_present.set 'Hello World!' 491 | The problem here is that you should never be using #set if you aren’t sure the element will be there or enabled, so these #when_present calls are philosophically redundant. 492 | 493 | As such, Watir 6.0 deprecated #when_present and #when_enabled and every action call on an element effectively executes this logic by default. 494 | 495 | Note that Watir does its automatic waiting when taking actions, not when attempting to locate. This provides additional flexibility for querying the state of an element without needing unnecessary waits. 496 | 497 | Watir Wait and Waitable Modules 498 | Waitable is the module that is included by Browser, Alert, Window and Element. This module provides access to two main methods: #wait_until and #wait_while. As of Watir 6, both of these methods accept :timeout, :message keyword parameters. Note that the :interval keyword was added in Watir 6.1 to allow reducing how often the condition is polled, and as of Watir 6.12 you can use a Proc instance value for :message if that is preferred to a String). Then as always, a block is passed in to establish what condition needs to be met. #wait_until will execute the block until a truthy result is returned, and #wait_while will execute the block until a falsy result is returned. 499 | 500 | browser.wait_until { |b| b.title == "Foo" } 501 | browser.window(title: "Foo")wait_while(&:exists?) 502 | browser.alert.wait_until { |a| a.text == "foo" } 503 | browser.button(name: 'submit').wait_until(&:enabled?) 504 | Note that it is encouraged to use #to_proc syntax when possible: 505 | 506 | # Good 507 | browser.text_field(title: 'Search').wait_until(message: "Can't find it" &:present?) 508 | 509 | # Less Good 510 | browser.text_field(title: 'Search').wait_until(message: "Can't find it") { |el| el.present? } 511 | The default timeout for Watir’s Waits is 30 seconds. You can pass in the :timeout keyword parameter to any of the wait methods, or you can change the global default with: 512 | 513 | Watir.default_timeout = 60 514 | Wait Until Present and Wait While Present 515 | There are two special waiting methods that apply only to Elements. As of Watir 6.2 for #wait_while_present and Watir 6.12 for #wait_until_present, these methods have subtly changed from their previous implementation. 516 | 517 | Most of the time you do not want to use these methods. In most circumstances you should use: 518 | 519 | browser.div(id: 'foo').wait_until(&:present?) 520 | browser.div(id: 'bar').wait_while(&:present?) 521 | But what if you have this element: 522 | 523 |
Foo
524 | and you locate it with this code: 525 | 526 | element = browser.div(class: "here") 527 | and then some dynamic event caused the element class to change: 528 | 529 |
Foo
530 | The element is still there, it just no longer corresponds to the selector Watir used to locate it. Because of how Watir caches elements for performance reasons, the following code will time out (Watir will just keep verifying that the cached element is still there): 531 | 532 | element.wait_while(&:present?) 533 | In this case we want the element to be looked up from scratch during the polling, which is what this does: 534 | 535 | element.wait_while_present 536 | Similarly for #wait_until_present, the scenario is when an element is located, then goes away, and you want to wait for it to come back. 537 | 538 | This will throw a Stale Element exception: 539 | 540 | element.wait_until(&:present?) 541 | This will return when the element has come back: 542 | 543 | element.wait_until_present 544 | 545 | ##Headless 546 | 547 | There are several options for running your tests headlessly. The first thing to consider is whether you actually need to run headless. Most options for this have limitations and require trade-offs. 548 | 549 | Traditionally PhantomJS has been an option for running headlessly. The driver for this virtual browser has been deprecated, though, so it is no longer supported in Watir. 550 | 551 | Perhaps the best option for running headlessly is using the Headless gem. The biggest limitation for this is that it only works on Unix based systems. It is the actual browser run in a virtual GUI. This is a great option for using a real world browser, albeit on a minimally used platform. 552 | 553 | Headless gem 554 | Code for the before hook: 555 | 556 | require 'watir' 557 | require 'headless' 558 | 559 | headless = Headless.new 560 | headless.start 561 | Code for the after hook: 562 | 563 | headless.destroy 564 | Browser specific options 565 | Both Chrome and Firefox have implemented headless modes for their browsers that work on all platforms. Recognize that this option does not include all of the browser code, so not all of the browser features are implemented, and this will not be an exact replication of what a user will see in a real browser. 566 | 567 | Headless on Chrome 568 | 569 | Headless on Firefox 570 | 571 | ##Basic Browser Authentication 572 | 573 | The easiest and most elegant way to handle basic browser authentication is to supply the username and password in the URL, bypassing the dialog altogether. 574 | 575 | b = Watir::Browser.start 'http://admin:password@yourwebsite.com' 576 | Proxy Authentication 577 | If the above method doesn’t work, eg. you are authenticating against a NTLM proxy, you may have find using the AutoAuth Firefox extension will enable you to automatically dismiss this dialog with your credentials. See this blog post for full details. 578 | 579 | ##Browser Certificates 580 | 581 | Firefox 582 | The Firefox driver properly handles untrusted certificates by default. 583 | 584 | If you have a trusted certificate, but there is some other certificate error such as a hostname mismatch (eg. using a production certificate in test), you should do the following: 585 | 586 | profile = Selenium::WebDriver::Firefox::Profile.new 587 | profile.assume_untrusted_certificate_issuer = false 588 | b = Watir::Browser.new :firefox, profile: profile 589 | The reason this is needed is explained here. 590 | 591 | Chrome 592 | It is easy to ignore invalid Browser certificates in Google Chrome by passing a command line switch: 593 | 594 | Watir::Browser.new :chrome, switches: ['--ignore-certificate-errors'] 595 | 596 | 597 | ##Browser Downloads 598 | 599 | Downloads are problematic in Watir because they require interacting with the Operating System, and Watir automates a Browser, not an OS. As such if any file dialog boxes are displayed, Watir will be unable to handle them. Especially if you are executing your tests on a remote machine, realize that downloads will be sent to that machine, not the machine executing your Ruby code, which makes retrieving the file effectively impossible. Additionally, actually validating the content of a file is not trivial, especially for something like a PDF. 600 | 601 | So, before we get into strategies for dealing with downloads, consider carefully whether you need to actually download files in the first place. 602 | 603 | Is it sufficient to validate that the link is present? 604 | Can you download the file with a an HTTP Library instead of going through the browser? 605 | Can you test what you need to in a lower level unit or integration test rather than in the browser? 606 | For more thoughts on this, read this article. It is older and focused on Selenium, but the points are still relevant. 607 | 608 | If your manager insists you absolutely must test the download via the browser, you can initialize the Browser object with parameters telling the browser to automatically download files to a particular directory rather than prompting the Operating System. 609 | 610 | Firefox 611 | download_directory = "#{Dir.pwd}/downloads" 612 | download_directory.tr!('/', '\\') if Selenium::WebDriver::Platform.windows? 613 | 614 | profile = Selenium::WebDriver::Firefox::Profile.new 615 | profile['browser.download.folderList'] = 2 # custom location 616 | profile['browser.download.dir'] = download_directory 617 | profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv,application/pdf' 618 | 619 | b = Watir::Browser.new :firefox, profile: profile 620 | A full list of these Firefox options are available in firefox by typing ‘about:config‘ in the address bar. 621 | 622 | If you want to know a way to work out the file types (eg. application/pdf) then you can read the following blog post for an step by step guide. 623 | 624 | Chrome 625 | prefs = { 626 | download: { 627 | prompt_for_download: false, 628 | default_directory: '/path/to/dir' 629 | } 630 | } 631 | 632 | b = Watir::Browser.new :chrome, options: {prefs: prefs} 633 | -------------------------------------------------------------------------------- 634 | 635 | ##Browser Popups 636 | 637 | When a new browser window is opened, you can then ‘use’ the new window. 638 | 639 | browser.window(title: 'annoying popup').use do 640 | browser.button(id: 'close').click 641 | end 642 | See the Window Switching Spec for more examples. 643 | ------------------------------------------------------------------------------ 644 | 645 | ##Browser Proxies 646 | 647 | In many cases, you can specify a proxy to use with the proxy: {} option. While each browser driver handles this slightly differently, the following format works in Chrome or Firefox. 648 | 649 | Example: using a proxy in Chrome or Firefox 650 | proxy = { 651 | http: 'my.proxy.com:8080', 652 | ssl: 'my.proxy.com:8080' 653 | } 654 | 655 | firefox_browser = Watir::Browser.new :firefox, proxy: proxy 656 | 657 | remote_firefox = Watir::Browser.new :firefox, url: REMOTE_SELENIUM, proxy: proxy 658 | 659 | chrome_browser = Watir::Browser.new :chrome, proxy: proxy 660 | 661 | remote_chrome = Watir::Browser.new :chrome, url: REMOTE_SELENIUM, proxy: proxy 662 | Be sure to specify both :http and :ssl to route both types of traffic through your proxy. 663 | 664 | Under the hood, this is passing options to create a Selenium::WebDriver::Proxy object. 665 | 666 | Example: setting a http and https proxy for Remote Chrome 667 | proxy = 'my.proxy.com:8080' 668 | browser = Watir::Browser.new :chrome, url: REMOTE_URL, proxy: {http: proxy, ssl: proxy} 669 | ------------------------------------------------------------------------------- 670 | 671 | ##Javascript Popups 672 | 673 | JavaScript dialogs are fairly common in web applications. 674 | 675 | Watir has an inbuilt library for handling these dialogs, and capturing values. 676 | 677 | Javascript Alerts 678 | # Check if alert is shown 679 | browser.alert.exists? 680 | 681 | # Get text of alert 682 | browser.alert.text 683 | 684 | # Close alert 685 | browser.alert.ok 686 | browser.alert.close 687 | Javascript Confirms 688 | # Accept confirm 689 | browser.alert.ok 690 | 691 | # Cancel confirm 692 | browser.alert.close 693 | Javascript Prompt 694 | # Enter text to prompt 695 | browser.alert.set 'Prompt answer' 696 | 697 | # Accept prompt 698 | browser.alert.ok 699 | 700 | # Cancel prompt 701 | browser.alert.close 702 | Alternative Method 703 | If you’re having trouble using the above method, you can override the JavaScript functions to return the value you want, so when they’re meant to show, they don’t! 704 | 705 | # don't return anything for alert 706 | browser.execute_script('window.alert = function() {}') 707 | 708 | # return some string for prompt to simulate user entering it 709 | browser.execute_script("window.prompt = function() {return 'my name'}") 710 | 711 | # return null for prompt to simulate clicking Cancel 712 | browser.execute_script('window.prompt = function() {return null}') 713 | 714 | # return true for confirm to simulate clicking OK 715 | browser.execute_script('window.confirm = function() {return true}') 716 | 717 | # return false for confirm to simulate clicking Cancel 718 | browser.execute_script('window.confirm = function() {return false}') 719 | 720 | # don't return anything for leave page popup 721 | browser.execute_script('window.onbeforeunload = null') 722 | ----------------------------------------------------------------------------- 723 | 724 | ##Measure Page Performance 725 | 726 | The Watir-Performance gem aims to provide a set of navigation timing metrics for Watir actions using a W3C page performance standard. This is a perfect solution to capture response time metrics, and it’s very straightforward to do. Works in Chrome, Firefox, Edge and IE9 and up. Currently no Safari support. 727 | 728 | require 'watir' 729 | require 'watir-performance' 730 | 731 | 10.times do 732 | b = Watir::Browser.new :chrome 733 | b.goto 'http://watir.com' 734 | load_secs = b.performance.summary[:response_time] / 1000 735 | puts "Load Time: #{load_secs} seconds." 736 | b.close 737 | end 738 | This produces something like: 739 | 740 | Load Time: 3.701 seconds. 741 | Load Time: 0.694 seconds. 742 | Load Time: 1.874 seconds. 743 | Load Time: 1.721 seconds. 744 | Load Time: 2.096 seconds. 745 | Load Time: 0.823 seconds. 746 | Load Time: 2.362 seconds. 747 | Load Time: 1.008 seconds. 748 | Load Time: 1.761 seconds. 749 | Load Time: 2.066 seconds. 750 | List of available metric groupings 751 | 752 | :summary 753 | :navigation 754 | :memory 755 | :timing 756 | ------------------------------------------------------------------------------- 757 | 758 | ##Page Objects 759 | 760 | The Page Object pattern is a way to represent pages and their elements in reusable classes. Page Objects eliminate duplication by building an abstraction that allows you to write browser tests for maximum maintainability and robustness. 761 | 762 | The Page Object pattern originated in WebDriver, and a great explanation (with examples in Java) can be found here. 763 | 764 | You create a Page object for each page of your application, which has methods that represent the services available on a given page. You should encapsulate all the implementation details of the system (i.e. HTML elements, waiting for the DOM to update etc) in these objects. Your test code (i.e. RSpec code blocks, Cucumber step definitions) should never access the underlying Browser instance or deal with HTML elements directly. 765 | 766 | In essence, you should have the mindset that your test code should not need to change if your web app was rewritten as a desktop app - you would simply need another implementation of the page object layer. Although strictly speaking a set of pages isn’t necessarily a good way to model a desktop application, having this in mind makes it easy to decide what should go where. 767 | 768 | The examples below assumes you are familiar with RSpec way of doing test assertions. 769 | 770 | Consider this script: 771 | 772 | browser = Watir::Browser.new 773 | browser.goto "http://example.com/login" 774 | 775 | browser.text_field(:name => "user").set "Mom" 776 | browser.text_field(:name => "pass").set "s3cr3t" 777 | browser.button(:id => "login").click 778 | 779 | Watir::Wait.until { browser.title == "Your Profile" } 780 | browser.div(:id => "logged-in").should exist 781 | With page objects, this could become: 782 | 783 | site = Site.new(Watir::Browser.new) 784 | 785 | login_page = site.login_page.open 786 | user_page = login_page.login_as "Mom", "s3cr3t" 787 | 788 | user_page.should be_logged_in 789 | An implementation of this could be: 790 | 791 | 792 | class BrowserContainer 793 | def initialize(browser) 794 | @browser = browser 795 | end 796 | end 797 | 798 | class Site < BrowserContainer 799 | def login_page 800 | @login_page = LoginPage.new(@browser) 801 | end 802 | 803 | def user_page 804 | @user_page = UserPage.new(@browser) 805 | end 806 | 807 | def close 808 | @browser.close 809 | end 810 | end # Site 811 | 812 | class LoginPage < BrowserContainer 813 | URL = "http://example.com/login" 814 | 815 | def open 816 | @browser.goto URL 817 | self 818 | end 819 | 820 | def login_as(user, pass) 821 | user_field.set user 822 | password_field.set pass 823 | 824 | login_button.click 825 | 826 | next_page = UserPage.new(@browser) 827 | Watir::Wait.until { next_page.loaded? } 828 | 829 | next_page 830 | end 831 | 832 | private 833 | 834 | def user_field 835 | @browser.text_field(:name => "user") 836 | end 837 | 838 | def password_field 839 | @browser.text_field(:name => "pass") 840 | end 841 | 842 | def login_button 843 | @browser.button(:id => "login") 844 | end 845 | end # LoginPage 846 | 847 | class UserPage < BrowserContainer 848 | def logged_in? 849 | logged_in_element.exists? 850 | end 851 | 852 | def loaded? 853 | @browser.title == "Your Profile" 854 | end 855 | 856 | private 857 | 858 | def logged_in_element 859 | @browser.div(:id => "logged-in") 860 | end 861 | end # UserPage 862 | This can then be integrated with other tools. For example, using Cucumber you could have this in env.rb: 863 | 864 | 865 | require "watir-webdriver" 866 | require "/path/to/site" 867 | 868 | module SiteHelper 869 | def site 870 | @site ||= ( 871 | Site.new(Watir::Browser.new(:firefox)) 872 | ) 873 | end 874 | end 875 | 876 | World(SiteHelper) 877 | And this step definition: 878 | 879 | 880 | Given /I have successfully logged in/ do 881 | login_page = site.login_page.open 882 | 883 | user_page = login_page.login_as "Mom", "s3cr3t" 884 | user_page.should be_logged_in 885 | end 886 | Assertions/expectations should be kept in your test code. Don’t use assertions in your page objects; instead ask them about their state, and assert on the result. E.g.: 887 | 888 | 889 | 890 | # 891 | # bad example 892 | # 893 | 894 | class SomePage 895 | def assert_loaded 896 | raise "not loaded" unless some_element.exists? 897 | end 898 | end 899 | 900 | it "should be loaded" do 901 | page.assert_loaded 902 | end 903 | 904 | # 905 | # good example 906 | # 907 | 908 | class SomePage 909 | def loaded? 910 | some_element.exists? 911 | end 912 | end 913 | 914 | it "should be loaded" do 915 | page.should be_loaded 916 | end 917 | See also: 918 | 919 | Page Object gems that work with Watir-webdriver 920 | 921 | Cheezy’s Page Object gem for Watir-webdriver and Selenium 922 | The rSmart Test-Factory gem for Page & Data objects using Watir-webdriver 923 | Watir Page Helper 924 | LoadableComponent 925 | Blog postings related to Page Objects and Watir-webdriver 926 | 927 | cheezyworld’s series on UI testing part 1, part 2, part 3, part 4, part 5 928 | Watermelon blog article on ‘roll your own’ page objects 929 | Blog postings related to Page Objects and webdriver/Selenium 930 | 931 | Page Objects on the Selenium Wiki 932 | Page Objects in Python 933 | Automated Testing using Page Objects and WebDriver 934 | Acceptance tests with JBehave, Selenium and Page Objects 935 | Using the Page Object pattern 936 | Selenium 2/Web Driver - the land where Page Objects are king! 937 | ------------------------------------------------------------------------------ 938 | ##Screenshots 939 | 940 | Watir has a pretty awesome screenshot capability, built right in. 941 | 942 | # Save screenshot to file 943 | browser.screenshot.save 'screenshot.png' 944 | 945 | # Represent screenshot as PNG image string 946 | browser.screenshot.png 947 | 948 | # Represent screenshot as Base64 encoded string 949 | browser.screenshot.base64 950 | The great thing about this is it gives you a screen shot of the entire page, not just above the fold. 951 | 952 | If you’re using Cucumber also, you can easily embed this in your html report output by adding the following to your env.rb file: 953 | 954 | After do |_scenario| 955 | browser.screenshot.save 'screenshot.png' 956 | embed 'screenshot.png', 'image/png' 957 | end 958 | ----------------------------------------------------------------------------- 959 | ##Sending Special Keys 960 | 961 | To send special keys to an element or browser page, you use the #send_keys method, with a symbolic representation of what you would like to send. 962 | 963 | b.send_keys :enter 964 | You can also do things like this: 965 | 966 | b.element.send_keys [:control, 'a'], :backspace 967 | You can also modify the click behaviour with keys: 968 | 969 | b.element.click(:shift, :control) 970 | The full list of keys are available from here: 971 | 972 | :null 973 | :cancel 974 | :help 975 | :backspace 976 | :tab 977 | :clear 978 | :return 979 | :enter 980 | :shift 981 | :left_shift 982 | :control 983 | :left_control 984 | :alt 985 | :left_alt 986 | :pause 987 | :escape 988 | :space 989 | :page_up 990 | :page_down 991 | :end 992 | :home 993 | :left 994 | :arrow_left 995 | :up 996 | :arrow_up 997 | :right 998 | :arrow_right 999 | :down 1000 | :arrow_down 1001 | :insert 1002 | :delete 1003 | :semicolon 1004 | :equals 1005 | :numpad0 1006 | :numpad1 1007 | :numpad2 1008 | :numpad3 1009 | :numpad4 1010 | :numpad5 1011 | :numpad6 1012 | :numpad7 1013 | :numpad8 1014 | :numpad9 1015 | :multiply 1016 | :add 1017 | :separator 1018 | :subtract 1019 | :decimal 1020 | :divide 1021 | :f1 1022 | :f2 1023 | :f3 1024 | :f4 1025 | :f5 1026 | :f6 1027 | :f7 1028 | :f8 1029 | :f9 1030 | :f10 1031 | :f11 1032 | :f12 1033 | :meta 1034 | :command 1035 | ---------------------------------------------------------------------------- 1036 | ##WYSIWYG Editors 1037 | 1038 | The recommended way to enter text into a WYSIWYG editor using Watir is to locate the iFrame, then find the and use the #send_keys method. 1039 | 1040 | Alternately you can execute javascript on the browser object that sets the value of the WYSIWYG editor. 1041 | 1042 | CKEditor 1043 | Recommended: 1044 | 1045 | b = Watir::Browser.new 1046 | b.goto 'http://nightly.ckeditor.com/18-08-02-06-04/standard/samples/' 1047 | b.iframe.body.wd.clear 1048 | b.iframe.body.send_keys "foo" 1049 | Note that this example no longer works. If anyone has a working example, please update this code 1050 | 1051 | b = Watir::Browser.new :firefox 1052 | b.goto 'http://nightly.ckeditor.com/18-08-02-06-04/standard/samples/' 1053 | b.execute_script("CKEDITOR.instances['editor1'].setData('hello world');") 1054 | f = b.frame(title: 'Rich text editor, editor1, press ALT 0 for help.') 1055 | f.send_keys 'hello world again' 1056 | TinyMCE Editor 1057 | Recommended: 1058 | 1059 | b = Watir::Browser.new 1060 | b.goto 'http://tinymce.moxiecode.com/tryit/full.php' 1061 | f = b.iframe(id: 'cp_embed_NGegZK').iframe(id: 'result-iframe') 1062 | wysiwg = f.iframe.body 1063 | wysiwg.wd.clear 1064 | wysiwg.send_keys "hello world" 1065 | Note that this example no longer works. If anyone has a working example, please update this code 1066 | 1067 | b = Watir::Browser.new 1068 | b.goto 'http://tinymce.moxiecode.com/tryit/full.php' 1069 | b.execute_script("tinyMCE.get('content').execCommand('mceSetContent',false, 'hello world' );") 1070 | b.frame(id: 'content_ifr').send_keys 'hello world again' 1071 | ------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /tests/apks/PreciseUnitConversion.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/PreciseUnitConversion.apk -------------------------------------------------------------------------------- /tests/apks/TrianguloApp.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/TrianguloApp.apk -------------------------------------------------------------------------------- /tests/apks/calculadora.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/calculadora.apk -------------------------------------------------------------------------------- /tests/apks/com.orgzly_60.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/com.orgzly_60.apk -------------------------------------------------------------------------------- /tests/apks/org.wikipedia_2.5.195-r-2017-04-21-195_minAPI16(arm64-v8a,armeabi,armeabi-v7a,mips,x86,x86_64)(nodpi)_apkmirror.com.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/org.wikipedia_2.5.195-r-2017-04-21-195_minAPI16(arm64-v8a,armeabi,armeabi-v7a,mips,x86,x86_64)(nodpi)_apkmirror.com.apk -------------------------------------------------------------------------------- /tests/apks/teste.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brunobatista25/best_archer/8b47150c30207c596beb8f38445bc85ded3a6e08/tests/apks/teste.apk --------------------------------------------------------------------------------