diff --git a/db.sqlite3 b/db.sqlite3 index 646aeef..71694ee 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/noticia/blog/forms.py b/noticia/blog/forms.py index a3476a4..7077df1 100644 --- a/noticia/blog/forms.py +++ b/noticia/blog/forms.py @@ -1,10 +1,21 @@ from django import forms -from .models import NewsItem +from .models import NewsItem, Event -class PostForm(forms.ModelForm): +class NewsItemForm(forms.ModelForm): + publish_date = forms.DateField(widget=forms.SelectDateWidget()) - class Meta: - model = NewsItem - fields = ('title', 'description', 'publish_date') + class Meta: + model = NewsItem + fields = ('title', 'description', 'publish_date') + + +class EventForm(forms.ModelForm): + + start_date = forms.DateField(widget=forms.SelectDateWidget()) + end_date = forms.DateField(widget=forms.SelectDateWidget()) + + class Meta: + model = Event + fields = ('title', 'description', 'start_date', 'end_date') diff --git a/noticia/blog/models.py b/noticia/blog/models.py index c716be8..b971eae 100644 --- a/noticia/blog/models.py +++ b/noticia/blog/models.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.utils import timezone from django.db import models -import datetime + # Create your models here. @@ -23,7 +23,7 @@ def __unicode__(self): class NewsItem(BaseNews): - publish_date = models.DateTimeField(blank=True, null=True) + publish_date = models.DateTimeField(blank=False, null=False) def publish(self): self.published_date = timezone.now() @@ -31,5 +31,5 @@ def publish(self): class Event(BaseNews): - start_date = models.DateTimeField(blank=True, null=True) - end_date = models.DateTimeField(blank=True, null=True) + start_date = models.DateTimeField(blank=False, null=False) + end_date = models.DateTimeField(blank=False, null=False) diff --git a/noticia/blog/serializers.py b/noticia/blog/serializers.py new file mode 100644 index 0000000..7591383 --- /dev/null +++ b/noticia/blog/serializers.py @@ -0,0 +1,16 @@ +from rest_framework import serializers +from .models import NewsItem, Event + + +class NewsItemSerializer(serializers.ModelSerializer): + + class Meta: + model = NewsItem + fields = ('id', 'title', 'description', 'publish_date') + + +class EventSerializer(serializers.ModelSerializer): + + class Meta: + model = Event + fields = ('id', 'title', 'description', 'start_date', 'end_date') diff --git a/noticia/blog/templates/blog/event_confirm_delete.html b/noticia/blog/templates/blog/event_confirm_delete.html index ff6ab61..13381b4 100644 --- a/noticia/blog/templates/blog/event_confirm_delete.html +++ b/noticia/blog/templates/blog/event_confirm_delete.html @@ -9,7 +9,7 @@
{% csrf_token %} ¿Estás seguro que deseas borrar el "{{ object }}"? - Regresar + Regresar
diff --git a/noticia/blog/templates/blog/event_detail.html b/noticia/blog/templates/blog/event_detail.html index 6e46b9e..8025e5f 100644 --- a/noticia/blog/templates/blog/event_detail.html +++ b/noticia/blog/templates/blog/event_detail.html @@ -13,7 +13,7 @@

{{ event.title }}

Editar Borrar - Regresar + Regresar

diff --git a/noticia/blog/templates/blog/event_form.html b/noticia/blog/templates/blog/event_form.html index 1b076b9..730e732 100644 --- a/noticia/blog/templates/blog/event_form.html +++ b/noticia/blog/templates/blog/event_form.html @@ -10,7 +10,7 @@ {% csrf_token %} {{ form.as_p }} - Regresar + Regresar diff --git a/noticia/blog/templates/blog/newsitem_confirm_delete.html b/noticia/blog/templates/blog/newsitem_confirm_delete.html index cc2fbcc..8e617f2 100644 --- a/noticia/blog/templates/blog/newsitem_confirm_delete.html +++ b/noticia/blog/templates/blog/newsitem_confirm_delete.html @@ -9,7 +9,7 @@
{% csrf_token %} ¿Estás seguro que deseas borrar la "{{ object }}"? - Regresar + Regresar
diff --git a/noticia/blog/templates/blog/newsitem_detail.html b/noticia/blog/templates/blog/newsitem_detail.html index c3f1287..44786c2 100644 --- a/noticia/blog/templates/blog/newsitem_detail.html +++ b/noticia/blog/templates/blog/newsitem_detail.html @@ -20,7 +20,7 @@

{{ newsitem.title }}

Editar v1 Borrar Borrar v1 - Regresar + Regresar

diff --git a/noticia/blog/templates/blog/newsitem_form.html b/noticia/blog/templates/blog/newsitem_form.html index 38f36da..63b5345 100644 --- a/noticia/blog/templates/blog/newsitem_form.html +++ b/noticia/blog/templates/blog/newsitem_form.html @@ -10,7 +10,7 @@ {% csrf_token %} {{ form.as_p }} - Regresar + Regresar diff --git a/noticia/blog/templates/blog/newsitem_list.html b/noticia/blog/templates/blog/newsitem_list.html index 95f144a..6d3a7a7 100644 --- a/noticia/blog/templates/blog/newsitem_list.html +++ b/noticia/blog/templates/blog/newsitem_list.html @@ -9,7 +9,8 @@ diff --git a/noticia/blog/templates/blog/newsitem_list.html~ b/noticia/blog/templates/blog/newsitem_list.html~ index 4663519..95f144a 100644 --- a/noticia/blog/templates/blog/newsitem_list.html~ +++ b/noticia/blog/templates/blog/newsitem_list.html~ @@ -9,15 +9,17 @@ -

hola

{% for post in NewsItem %}
-

{{ post.title }}

+

{{ post.title }}

{{ post.description}}

Publicación de la noticia: {{ post.publish_date }}

-
+ {% endfor %} + Regresar diff --git a/noticia/blog/tests.py b/noticia/blog/tests.py index 7ce503c..037dfef 100644 --- a/noticia/blog/tests.py +++ b/noticia/blog/tests.py @@ -1,3 +1,163 @@ from django.test import TestCase +from django.utils import timezone +from django.core.urlresolvers import reverse +from .models import NewsItem, Event +from .views import NewsItemForm, EventForm +from rest_framework.test import APITestCase +from rest_framework import status -# Create your tests here. + +def news_example(title): + ahora = timezone.now() + return NewsItem.objects.create(title=title, description="prueba descripcion", publish_date=ahora) + + +def event_example(title): + ahora = timezone.now() + return Event.objects.create(title=title, description="prueba descripcion", start_date=ahora, end_date=ahora) + + +class NewsItemEventTest(TestCase): + + def test_index(self): + resp = self.client.get(reverse('blog:index')) + self.assertEqual(resp.status_code, 200) + + def test_noticia(self): + resp = self.client.get(reverse('blog:noticias')) + self.assertEqual(resp.status_code, 200) + + def test_evento(self): + resp = self.client.get(reverse('blog:eventos')) + self.assertEqual(resp.status_code, 200) + + def test_both(self): + resp = self.client.get(reverse('blog:todo')) + self.assertEqual(resp.status_code, 200) + + def test_class_form(self): + data = {'title': "titulo", 'description': "descripcion", 'publish_date': timezone.now()} + form = NewsItemForm(data=data) + form.save() + self.assertTrue(form.is_valid()) + x = NewsItem.objects.get(title="titulo") + self.assertTrue(x) + + def test_v2detail(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:detailnews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + + def test_v1detail(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:1detailnews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + + def test_news_create_v1(self): + resp = self.client.get(reverse('blog:1newnews')) + self.assertContains(resp, 'Publicar') + + def test_news_create_v2(self): + resp = self.client.get(reverse('blog:newnews')) + self.assertContains(resp, 'Publicar') + + def test_news_edit_v1(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:v1editnews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + resp = self.client.get(reverse('blog:noticias')) + self.assertEqual(resp.status_code, 200) + + def test_news_edit_v2(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:editnews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + + def test_news_delete_v1(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:v1deletenews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + self.assertContains(resp, 'borrar') + + def test_news_delete_v2(self): + w = news_example("prueba") + resp = self.client.get(reverse('blog:deletenews', kwargs={'pk': w.id})) + self.assertEqual(resp.status_code, 200) + self.assertContains(resp, 'borrar') + + def test_eventdetail(self): + z = event_example("prueba") + resp = self.client.get(reverse('blog:detailevent', kwargs={'pk': z.id})) + self.assertEqual(resp.status_code, 200) + + def test_eventcreate(self): + resp = self.client.get(reverse('blog:newevent')) + self.assertContains(resp, 'Publicar') + + def test_eventedit(self): + z = event_example("prueba") + resp = self.client.get(reverse('blog:editevent', kwargs={'pk': z.id})) + self.assertEqual(resp.status_code, 200) + + def test_eventdelete(self): + z = event_example("prueba") + resp = self.client.get(reverse('blog:deleteevent', kwargs={'pk': z.id})) + self.assertEqual(resp.status_code, 200) + self.assertContains(resp, 'borrar') + +""" API TEST """ + + +class NewsItemListAPITestCase(APITestCase): + + def addNewsItem(self): + form = NewsItemForm(data={'title': "titulo", 'description': "descripcion", 'publish_date': timezone.now()}) + form.is_valid() + form.save() + return NewsItem.objects.get(title='titulo') + + def test_create(self): + data = {'title': "prueba", 'description': "prueba", 'publish_date': timezone.now()} + response = self.client.post(reverse('blog:apiNewsItem'), data, format="json") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(NewsItem.objects.get().title, 'prueba') + + def test_read(self): + response = self.client.get(reverse('blog:apiNewsItem')) + self.assertEqual(response.status_code, 200) + + def test_update_delete(self): + self.addNewsItem() + x = NewsItem.objects.get(title='titulo') + update = {'title': 'clave', 'description': 'clave', 'publish_date': timezone.now()} + response = self.client.patch(reverse('blog:apiDetailNewsItem', kwargs={'pk': x.id}), update, format="json") + self.assertEqual(response.status_code, 200) + self.assertEqual(NewsItem.objects.get().title, 'clave') + + +class EventAPITestCase(APITestCase): + + def addEvent(self): + form = EventForm(data={'title': 'titulo', 'description': 'descripcion', 'start_date': timezone.now(), 'end_date': timezone.now()}) + form.is_valid() + form.save() + return Event.objects.get(title="titulo") + + def test_create(self): + data = {'title': 'prueba', 'description': 'prueba', 'start_date': timezone.now(), 'end_date': timezone.now()} + response = self.client.post(reverse('blog:apiEvent'), data, format="json") + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Event.objects.get().title, 'prueba') + + def test_read(self): + response = self.client.get(reverse('blog:apiEvent')) + self.assertEqual(response.status_code, 200) + + def test_update_delete(self): + self.addEvent() + x = Event.objects.get(title='titulo') + update = {'title': 'prueba', 'description': 'prueba', 'start_date': timezone.now(), 'end_date': timezone.now()} + response = self.client.patch(reverse('blog:apiDetailEvent', kwargs={'pk': x.id}), update, format="json") + self.assertEqual(response.status_code, 200) + self.assertEqual(Event.objects.get().title, 'prueba') + diff --git a/noticia/blog/urls.py b/noticia/blog/urls.py index 5093965..31238ff 100644 --- a/noticia/blog/urls.py +++ b/noticia/blog/urls.py @@ -1,36 +1,44 @@ from django.conf.urls import url from .views import ( - NewsItemList, + # NewsItemList, NewsItemDetail, NewsItemCreation, NewsItemUpdate, NewsItemDelete, - EventList, + #EventList, EventDetail, EventCreation, EventUpdate, - EventDelete + EventDelete, ) from . import views +from rest_framework.urlpatterns import format_suffix_patterns app_name = 'blog' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^todo/$', views.todo, name='todo'), url(r'^noticias/$', views.newsitem_list, name='noticias'), - url(r'^noticias/$', NewsItemList.as_view(), name='listnews'), - url(r'^noticias/(?P[0-9]+)/$', NewsItemDetail.as_view(), name='detailnews'), + # url(r'^noticias/$', NewsItemList.as_view(), name='listnews'), + url(r'^noticias/v2/(?P[0-9]+)/$', NewsItemDetail.as_view(), name='detailnews'), url(r'^noticias/v2/nuevo$', NewsItemCreation.as_view(), name='newnews'), url(r'^noticias/v2/(?P[0-9]+)/editar/$', NewsItemUpdate.as_view(), name='editnews'), url(r'^noticias/v2/borrar/(?P[0-9]+)/$', NewsItemDelete.as_view(), name='deletenews'), url(r'^eventos/$', views.event_list, name='eventos'), - url(r'^eventos/$', EventList.as_view(), name='listevent'), + #url(r'^eventos/$', EventList.as_view(), name='listevent'), url(r'^eventos/(?P[0-9]+)/$', EventDetail.as_view(), name='detailevent'), url(r'^eventos/nuevo$', EventCreation.as_view(), name='newevent'), url(r'^eventos/editar/(?P[0-9]+)/$', EventUpdate.as_view(), name='editevent'), url(r'^eventos/borrar/(?P[0-9]+)/$', EventDelete.as_view(), name='deleteevent'), #noticias v1 - url(r'^noticias/$', views.newsitem_list, name='noticias'), url(r'^noticias/v1/nuevo$', views.newsitem_create, name='1newnews'), + url(r'^noticias/v1/(?P[0-9]+)/$', NewsItemDetail.as_view(), name='1detailnews'), url(r'^noticias/v1/(?P[0-9]+)/editar$', views.newsitem_update, name='v1editnews'), - url(r'^noticias/v1/(?P[0-9]+)/borrar$', views.newsitem_delete, name='v1deletenews'), + url(r'^noticias/v1/borrar/(?P[0-9]+)/$', views.newsitem_delete, name='v1deletenews'), +#api newsitem + url(r'^apinews/$', views.NewsItemapi.as_view(), name="apiNewsItem"), + url(r'^apinews/(?P[0-9]+)/$', views.NewsItemDetailapi.as_view(), name="apiDetailNewsItem"), +#api event + url(r'^apievent/$', views.EventListapi.as_view(), name="apiEvent"), + url(r'^apievent/(?P[0-9]+)/$', views.EventDetailapi.as_view(), name="apiDetailEvent"), ] +urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/noticia/blog/views.py b/noticia/blog/views.py index 8d3b613..b59c784 100644 --- a/noticia/blog/views.py +++ b/noticia/blog/views.py @@ -11,13 +11,9 @@ from django.utils import timezone from .models import Event from django.shortcuts import redirect, get_object_or_404 -from django.forms import ModelForm - - -class NewsItemForm(ModelForm): - class Meta: - model = NewsItem - fields = ['title', 'description', 'publish_date'] +from .forms import NewsItemForm, EventForm +from .serializers import NewsItemSerializer, EventSerializer +from rest_framework import generics def newsitem_list1(request, template_name='blog/newsitem_list.html'): @@ -31,7 +27,7 @@ def newsitem_create(request, template_name='blog/newsitem_form.html'): form = NewsItemForm(request.POST or None) if form.is_valid(): form.save() - return redirect('blog:listnews') + return redirect('blog:noticias') return render(request, template_name, {'form': form}) @@ -40,7 +36,7 @@ def newsitem_update(request, pk, template_name='blog/newsitem_form.html'): form = NewsItemForm(request.POST or None, instance=post) if form.is_valid(): form.save() - return redirect('blog:listnews') + return redirect('blog:noticias') return render(request, template_name, {'form': form}) @@ -48,7 +44,7 @@ def newsitem_delete(request, pk, template_name='blog/newsitem_confirm_delete.htm post = get_object_or_404(NewsItem, pk=pk) if request.method == 'POST': post.delete() - return redirect('blog:listnews') + return redirect('blog:noticias') return render(request, template_name, {'object': post}) @@ -77,19 +73,20 @@ class NewsItemDetail(DetailView): class NewsItemCreation(CreateView): model = NewsItem - success_url = reverse_lazy('blog:listnews') - fields = ['title', 'description', 'publish_date'] + success_url = reverse_lazy('blog:noticias') + #ields = ['title', 'description', 'publish_date'] + form_class = NewsItemForm class NewsItemUpdate(UpdateView): model = NewsItem - success_url = reverse_lazy('blog:listnews') + success_url = reverse_lazy('blog:noticias') fields = ['title', 'description', 'publish_date'] class NewsItemDelete(DeleteView): model = NewsItem - success_url = reverse_lazy('blog:listnews') + success_url = reverse_lazy('blog:noticias') def event_list(request): @@ -107,16 +104,40 @@ class EventDetail(DetailView): class EventCreation(CreateView): model = Event - success_url = reverse_lazy('blog:listevent') - fields = ['title', 'description', 'start_date', 'end_date'] + success_url = reverse_lazy('blog:eventos') + """fields = ['title', 'description', 'start_date', 'end_date']""" + form_class = EventForm class EventUpdate(UpdateView): model = Event - success_url = reverse_lazy('blog:listevent') - fields = ['title', 'description', 'start_date', 'end_date'] - + success_url = reverse_lazy('blog:eventos') + """fields = ['title', 'description', 'start_date', 'end_date']""" + form_class = EventForm class EventDelete(DeleteView): model = Event - success_url = reverse_lazy('blog:listevent') + success_url = reverse_lazy('blog:eventos') + + +class NewsItemapi(generics.ListCreateAPIView): + + queryset = NewsItem.objects.all() + serializer_class = NewsItemSerializer + + +class NewsItemDetailapi(generics.RetrieveUpdateDestroyAPIView): + + queryset = NewsItem.objects.all() + serializer_class = NewsItemSerializer + + +class EventListapi(generics.ListCreateAPIView): + queryset = Event.objects.all() + serializer_class = EventSerializer + + +class EventDetailapi(generics.RetrieveUpdateDestroyAPIView): + + queryset = Event.objects.all() + serializer_class = EventSerializer diff --git a/noticia/blog/views.py~ b/noticia/blog/views.py~ new file mode 100644 index 0000000..8423b32 --- /dev/null +++ b/noticia/blog/views.py~ @@ -0,0 +1,115 @@ +from django.core.urlresolvers import reverse_lazy +from django.views.generic import ListView +from django.views.generic.detail import DetailView +from django.views.generic.edit import ( + CreateView, + UpdateView, + DeleteView + ) +from .models import NewsItem +from django.shortcuts import render +from django.utils import timezone +from .models import Event +from django.shortcuts import redirect, get_object_or_404 +from .forms import NewsItemForm + +def newsitem_list1(request, template_name='blog/newsitem_list.html'): + posts = NewsItem.objects.all() + data = {} + data['object_list'] = posts + return render(request, template_name, data) + + +def newsitem_create(request, template_name='blog/newsitem_form.html'): + form = NewsItemForm(request.POST or None) + if form.is_valid(): + form.save() + return redirect('blog:listnews') + return render(request, template_name, {'form': form}) + + +def newsitem_update(request, pk, template_name='blog/newsitem_form.html'): + post = get_object_or_404(NewsItem, pk=pk) + form = NewsItemForm(request.POST or None, instance=post) + if form.is_valid(): + form.save() + return redirect('blog:listnews') + return render(request, template_name, {'form': form}) + + +def newsitem_delete(request, pk, template_name='blog/newsitem_confirm_delete.html'): + post = get_object_or_404(NewsItem, pk=pk) + if request.method == 'POST': + post.delete() + return redirect('blog:listnews') + return render(request, template_name, {'object': post}) + + +def index(request): + return render(request, 'blog/index.html', {}) + + +def todo(request): + post = NewsItem.objects.filter(publish_date__lte=timezone.now()).order_by('publish_date') + event = Event.objects.filter(start_date__lte=timezone.now()).order_by('start_date') + return render(request, 'blog/both_list.html', {'NewsItem': post, 'Event': event}) + + +def newsitem_list(request): + post = NewsItem.objects.filter(publish_date__lte=timezone.now()).order_by('publish_date') + return render(request, 'blog/newsitem_list.html', {'NewsItem': post}) + + +class NewsItemList(ListView): + model = NewsItem + + +class NewsItemDetail(DetailView): + model = NewsItem + + +class NewsItemCreation(CreateView): + model = NewsItem + success_url = reverse_lazy('blog:listnews') + fields = ['title', 'description', 'publish_date'] + + +class NewsItemUpdate(UpdateView): + model = NewsItem + success_url = reverse_lazy('blog:listnews') + fields = ['title', 'description', 'publish_date'] + + +class NewsItemDelete(DeleteView): + model = NewsItem + success_url = reverse_lazy('blog:listnews') + + +def event_list(request): + event = Event.objects.all().order_by('start_date') + return render(request, 'blog/event_list.html', {'Event': event}) + + +class EventList(ListView): + model = Event + + +class EventDetail(DetailView): + model = Event + + +class EventCreation(CreateView): + model = Event + success_url = reverse_lazy('blog:listevent') + fields = ['title', 'description', 'start_date', 'end_date'] + + +class EventUpdate(UpdateView): + model = Event + success_url = reverse_lazy('blog:listevent') + fields = ['title', 'description', 'start_date', 'end_date'] + + +class EventDelete(DeleteView): + model = Event + success_url = reverse_lazy('blog:listevent') diff --git a/noticia/settings.py b/noticia/settings.py index 4d23f17..b8e3213 100644 --- a/noticia/settings.py +++ b/noticia/settings.py @@ -37,7 +37,9 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'blog', + 'noticia.blog', + 'django_nose', + 'rest_framework', ] MIDDLEWARE_CLASSES = [ @@ -52,7 +54,10 @@ ] ROOT_URLCONF = 'noticia.urls' - +TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' +NOSE_ARGS = [ + '--with-coverage', +] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', diff --git a/noticia/settings.py~ b/noticia/settings.py~ new file mode 100644 index 0000000..4d23f17 --- /dev/null +++ b/noticia/settings.py~ @@ -0,0 +1,123 @@ +""" +Django settings for noticia project. + +Generated by 'django-admin startproject' using Django 1.9. + +For more information on this file, see +https://docs.djangoproject.com/en/1.9/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.9/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '*=80z8n+1mf_kf_fvm)%t5$!9io53(+@ulf0d(4nde0&ui$io!' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'blog', +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'noticia.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'noticia.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.9/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.9/topics/i18n/ + +LANGUAGE_CODE = 'es-es' + +TIME_ZONE = 'Europe/Madrid' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.9/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') diff --git a/noticia/urls.py b/noticia/urls.py index 17b8b8e..f8a8777 100644 --- a/noticia/urls.py +++ b/noticia/urls.py @@ -19,5 +19,5 @@ urlpatterns = [ url(r'^admin/', include(admin.site.urls)), - url(r'', include('blog.urls')), + url(r'', include('noticia.blog.urls')), ] diff --git a/noticia/urls.py~ b/noticia/urls.py~ new file mode 100644 index 0000000..17b8b8e --- /dev/null +++ b/noticia/urls.py~ @@ -0,0 +1,23 @@ +"""noticia URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.9/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Add an import: from blog import urls as blog_urls + 2. Import the include() function: from django.conf.urls import url, include + 3. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) +""" +from django.conf.urls import url, include +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'', include('blog.urls')), +] diff --git a/qa_selenium/.gitignore b/qa_selenium/.gitignore new file mode 100644 index 0000000..ef56cf2 --- /dev/null +++ b/qa_selenium/.gitignore @@ -0,0 +1,6 @@ +/target/ +.classpath +.project +/.settings/ +/test-output/ + diff --git a/qa_selenium/pom.xml b/qa_selenium/pom.xml new file mode 100644 index 0000000..2612ba2 --- /dev/null +++ b/qa_selenium/pom.xml @@ -0,0 +1,212 @@ + + 4.0.0 + com.emergya + qa_selenium + 0.0.1-SNAPSHOT + + + + UTF-8 + UTF-8 + 2.53.0 + 1.7 + 3.1 + 6.8.8 + 1.0.1 + 1.1 + 1.1.6 + 1.0-FCS + 1.0-FCS + 3.0 + 1.2.17 + + + Firefox + Ubuntu + false + target/surefire-reports/testCasesVideos + true + false + + + + localhost:8000/admin + + + + + + + QA-ENV + + ****URL**** + ****CONTEXT**** + + + + + STG-ENV + + ****URL**** + ****CONTEXT**** + + + + + + Mode-Dev + + false + false + + + + + Mode-Jenkins + + true + false + + + + + Mode-Debug + + true + true + + + + + + Emergya-Acceptance + + src/test/resources/suites/emergyaAcceptanceTest.xml + + + + + Emergya-Regression + + src/test/resources/suites/emergyaRegressionTest.xml + + + + + + + central + Maven Repository Switchboard + default + http://repo1.maven.org/maven2 + + false + + + + + + + org.testng + testng + ${testng.version} + + + + org.seleniumhq.selenium + selenium-java + ${selenium.version} + + + + com.pojosontheweb + monte-repack + ${monte.repack.version} + + + + org.jdom + jdom + ${jdom.version} + + + + jaxen + jaxen + ${jaxen.version} + + + + saxpath + saxpath + ${saxpath.version} + + + + org.jdom + jaxen-jdom + ${jaxen.jdom.version} + + + + org.apache.commons + commons-lang3 + ${commons.version} + + + + log4j + log4j + ${log4j.version} + + + com.sun.jmx + jmxri + + + com.sun.jdmk + jmxtools + + + javax.jms + jms + + + + + + + + + + + src/test/resources + true + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.16 + + + src/test/resources/suites/emergyaAcceptanceTest.xml + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + diff --git a/qa_selenium/src/main/java/com/emergya/drivers/EmergyaChromeDriver.java b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaChromeDriver.java new file mode 100644 index 0000000..1dee3e3 --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaChromeDriver.java @@ -0,0 +1,212 @@ +package com.emergya.drivers; + +import org.openqa.selenium.By; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + +/** + * Custom driver for chrome + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + */ +public class EmergyaChromeDriver extends ChromeDriver + implements EmergyaWebDriver { + + /** + * Constructor + */ + public EmergyaChromeDriver() { + super(); + } + + public EmergyaChromeDriver(ChromeOptions chromeOptions) { + super(chromeOptions); + } + + // **** Basic operation methods section ****// + /** + * Checks if an element exists in the DOM + * @param selector By element + * @return True if the element exists in the DOM and false in the opposite case + */ + public boolean existsElement(By selector) { + return EmergyaWebDriverUtil.existsElement(this, selector); + } + + /** + * Checks if an element exists in the DOM and is displayed + * @param selector By element + * @return True if the element exists in the DOM and is displayed and false in the opposite case + */ + public boolean isElementDisplayed(By selector) { + return EmergyaWebDriverUtil.isElementDisplayed(this, selector); + } + + /** + * Clicks on an element after wait and if it is displayed + * @param selector By element + */ + public void clickIfExists(By selector) { + EmergyaWebDriverUtil.clickIfExists(this, selector); + } + + // **** Javascript methods section ****// + /** + * Executes JavaScript in the context of the currently window + * @param script The JavaScript to execute + * @return Boolean, Long, String, List, WebElement Or null + */ + public Object executeJavaScript(String script) { + return EmergyaWebDriverUtil.executeJavaScript(this, script); + } + + /** + * Puts the focus on an element through its id + * @param driver WebDriver element + * @param id string with the id of an element + */ + public void focus(String id) { + EmergyaWebDriverUtil.focus(this, id); + } + + // **** Screenshot methods section ****// + /** + * Saves a screenshot in a path with a timestamp + * @param folderPath to save the screenshot + * @param baseFileName file name + */ + public void saveScreenshotPath(String folderPath, String baseFileName) { + EmergyaWebDriverUtil.saveScreenshotPath(this, folderPath, baseFileName); + } + + /** + * Saves a screenshot in the default path + * @param driver WebDriver element + */ + public void saveScreenshotDefault() { + EmergyaWebDriverUtil.saveScreenshotDefault(this); + } + + // **** Sleep method ****// + /** + * Stops the execution during some seconds + * @param seconds time to stop the execution + */ + public void sleep(int seconds) { + EmergyaWebDriverUtil.sleep(seconds); + } + + // **** Keyboard events methods section ****// + /** + * Presses a keyboard key + * @param key to press + * @param sleepTime time to wait before and after to press the key + */ + public void pressKey(int key, int sleepTime) { + EmergyaWebDriverUtil.pressKey(key, sleepTime); + } + + /** + * Releases a keyboard key + * @param key to release + * @param sleepTime time to wait before and after to release the key + */ + public void releaseKey(int key, int sleepTime) { + EmergyaWebDriverUtil.releaseKey(key, sleepTime); + } + + /** + * Presses and releases a keyboard key + * @param key to press and release + */ + public void pressReleaseKey(int key) { + EmergyaWebDriverUtil.pressReleaseKey(key); + } + + // **** Mouse events methods section ****// + /** + * Moves the mouse over an element + * @param selector By element + */ + public void moveMouseOverElement(By selector) { + EmergyaWebDriverUtil.moveMouseOverElement(this, selector); + } + + /** + * Moves the mouse out of an element + * @param selector By element + */ + public void moveMouseOutElement(By selector) { + EmergyaWebDriverUtil.moveMouseOutElement(this, selector); + } + + /** + * Clicks with the mouse on an element + * @param selector By element + */ + public void clickOnWithMouse(By selector) { + EmergyaWebDriverUtil.clickOnWithMouse(this, selector); + } + + /** + * Clicks with the mouse out of an element + * @param selector By element + */ + public void clickOutWithMouse(By selector) { + EmergyaWebDriverUtil.clickOutWithMouse(this, selector); + } + + /** + * Double clicks with the mouse on an element + * @param selector By element + */ + public void doubleClickOnWithMouse(By selector) { + EmergyaWebDriverUtil.doubleClickOnWithMouse(this, selector); + + } + + // **** Wait methods section ****// + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element exist in the DOM and false in the opposite case + */ + public boolean wait(By selector, long seconds) { + return EmergyaWebDriverUtil.wait(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is visible in the page and false in the opposite case + */ + public boolean waitUntilVisible(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilVisible(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is clickable in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is clickable in the page and false in the opposite case + */ + public boolean waitUntilElementClickable(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilElementClickable(this, selector, + seconds); + } + + /** + * It sleeps the driver for X seconds. If the text is present in element, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @param text to be find + * @return true If the text is present in element, and false in the opposite case + */ + public boolean waitUntilTextPresent(By selector, long seconds, + String text) { + return EmergyaWebDriverUtil.waitUntilTextPresent(this, selector, + seconds, text); + } +} diff --git a/qa_selenium/src/main/java/com/emergya/drivers/EmergyaFirefoxDriver.java b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaFirefoxDriver.java new file mode 100644 index 0000000..012c739 --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaFirefoxDriver.java @@ -0,0 +1,217 @@ +package com.emergya.drivers; + +import org.openqa.selenium.By; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.firefox.FirefoxProfile; +import org.openqa.selenium.remote.DesiredCapabilities; + +/** + * Custom driver for firefox + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + */ +public class EmergyaFirefoxDriver extends FirefoxDriver + implements EmergyaWebDriver { + + /** + * Constructor + */ + public EmergyaFirefoxDriver() { + super(); + } + + public EmergyaFirefoxDriver(DesiredCapabilities capabilities) { + super(capabilities); + } + + public EmergyaFirefoxDriver(FirefoxProfile profile) { + super(profile); + } + + // **** Basic operation methods section ****// + /** + * Checks if an element exists in the DOM + * @param selector By element + * @return True if the element exists in the DOM and false in the opposite case + */ + public boolean existsElement(By selector) { + return EmergyaWebDriverUtil.existsElement(this, selector); + } + + /** + * Checks if an element exists in the DOM and is displayed + * @param selector By element + * @return True if the element exists in the DOM and is displayed and false in the opposite case + */ + public boolean isElementDisplayed(By selector) { + return EmergyaWebDriverUtil.isElementDisplayed(this, selector); + } + + /** + * Clicks on an element after wait and if it is displayed + * @param selector By element + */ + public void clickIfExists(By selector) { + EmergyaWebDriverUtil.clickIfExists(this, selector); + } + + // **** Javascript methods section ****// + /** + * Executes JavaScript in the context of the currently window + * @param script The JavaScript to execute + * @return Boolean, Long, String, List, WebElement Or null + */ + public Object executeJavaScript(String script) { + return EmergyaWebDriverUtil.executeJavaScript(this, script); + } + + /** + * Puts the focus on an element through its id + * @param driver WebDriver element + * @param id string with the id of an element + */ + public void focus(String id) { + EmergyaWebDriverUtil.focus(this, id); + } + + // **** Screenshot methods section ****// + /** + * Saves a screenshot in a path with a timestamp + * @param folderPath to save the screenshot + * @param baseFileName file name + */ + public void saveScreenshotPath(String folderPath, String baseFileName) { + EmergyaWebDriverUtil.saveScreenshotPath(this, folderPath, baseFileName); + } + + /** + * Saves a screenshot in the default path + * @param driver WebDriver element + */ + public void saveScreenshotDefault() { + EmergyaWebDriverUtil.saveScreenshotDefault(this); + } + + // **** Sleep method ****// + /** + * Stops the execution during some seconds + * @param seconds time to stop the execution + */ + public void sleep(int seconds) { + EmergyaWebDriverUtil.sleep(seconds); + } + + // **** Keyboard events methods section ****// + /** + * Presses a keyboard key + * @param key to press + * @param sleepTime time to wait before and after to press the key + */ + public void pressKey(int key, int sleepTime) { + EmergyaWebDriverUtil.pressKey(key, sleepTime); + } + + /** + * Releases a keyboard key + * @param key to release + * @param sleepTime time to wait before and after to release the key + */ + public void releaseKey(int key, int sleepTime) { + EmergyaWebDriverUtil.releaseKey(key, sleepTime); + } + + /** + * Presses and releases a keyboard key + * @param key to press and release + */ + public void pressReleaseKey(int key) { + EmergyaWebDriverUtil.pressReleaseKey(key); + } + + // **** Mouse events methods section ****// + /** + * Moves the mouse over an element + * @param selector By element + */ + public void moveMouseOverElement(By selector) { + EmergyaWebDriverUtil.moveMouseOverElement(this, selector); + } + + /** + * Moves the mouse out of an element + * @param selector By element + */ + public void moveMouseOutElement(By selector) { + EmergyaWebDriverUtil.moveMouseOutElement(this, selector); + } + + /** + * Clicks with the mouse on an element + * @param selector By element + */ + public void clickOnWithMouse(By selector) { + EmergyaWebDriverUtil.clickOnWithMouse(this, selector); + } + + /** + * Clicks with the mouse out of an element + * @param selector By element + */ + public void clickOutWithMouse(By selector) { + EmergyaWebDriverUtil.clickOutWithMouse(this, selector); + } + + /** + * Double clicks with the mouse on an element + * @param selector By element + */ + public void doubleClickOnWithMouse(By selector) { + EmergyaWebDriverUtil.doubleClickOnWithMouse(this, selector); + + } + + // **** Wait methods section ****// + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element exist in the DOM and false in the opposite case + */ + public boolean wait(By selector, long seconds) { + return EmergyaWebDriverUtil.wait(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is visible in the page and false in the opposite case + */ + public boolean waitUntilVisible(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilVisible(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is clickable in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is clickable in the page and false in the opposite case + */ + public boolean waitUntilElementClickable(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilElementClickable(this, selector, + seconds); + } + + /** + * It sleeps the driver for X seconds. If the text is present in element, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @param text to be find + * @return true If the text is present in element, and false in the opposite case + */ + public boolean waitUntilTextPresent(By selector, long seconds, + String text) { + return EmergyaWebDriverUtil.waitUntilTextPresent(this, selector, + seconds, text); + } +} diff --git a/qa_selenium/src/main/java/com/emergya/drivers/EmergyaIEDriver.java b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaIEDriver.java new file mode 100644 index 0000000..df47d3a --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaIEDriver.java @@ -0,0 +1,207 @@ +package com.emergya.drivers; + +import org.openqa.selenium.By; +import org.openqa.selenium.ie.InternetExplorerDriver; + +/** + * Custom driver for internet explorer + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + */ +public class EmergyaIEDriver extends InternetExplorerDriver + implements EmergyaWebDriver { + + /** + * Constructor + */ + public EmergyaIEDriver() { + super(); + } + + // **** Basic operation methods section ****// + /** + * Checks if an element exists in the DOM + * @param selector By element + * @return True if the element exists in the DOM and false in the opposite case + */ + public boolean existsElement(By selector) { + return EmergyaWebDriverUtil.existsElement(this, selector); + } + + /** + * Checks if an element exists in the DOM and is displayed + * @param selector By element + * @return True if the element exists in the DOM and is displayed and false in the opposite case + */ + public boolean isElementDisplayed(By selector) { + return EmergyaWebDriverUtil.isElementDisplayed(this, selector); + } + + /** + * Clicks on an element after wait and if it is displayed + * @param selector By element + */ + public void clickIfExists(By selector) { + EmergyaWebDriverUtil.clickIfExists(this, selector); + } + + // **** Javascript methods section ****// + /** + * Executes JavaScript in the context of the currently window + * @param script The JavaScript to execute + * @return Boolean, Long, String, List, WebElement Or null + */ + public Object executeJavaScript(String script) { + return EmergyaWebDriverUtil.executeJavaScript(this, script); + } + + /** + * Puts the focus on an element through its id + * @param driver WebDriver element + * @param id string with the id of an element + */ + public void focus(String id) { + EmergyaWebDriverUtil.focus(this, id); + } + + // **** Screenshot methods section ****// + /** + * Saves a screenshot in a path with a timestamp + * @param folderPath to save the screenshot + * @param baseFileName file name + */ + public void saveScreenshotPath(String folderPath, String baseFileName) { + EmergyaWebDriverUtil.saveScreenshotPath(this, folderPath, baseFileName); + } + + /** + * Saves a screenshot in the default path + * @param driver WebDriver element + */ + public void saveScreenshotDefault() { + EmergyaWebDriverUtil.saveScreenshotDefault(this); + } + + // **** Sleep method ****// + /** + * Stops the execution during some seconds + * @param seconds time to stop the execution + */ + public void sleep(int seconds) { + EmergyaWebDriverUtil.sleep(seconds); + } + + // **** Keyboard events methods section ****// + /** + * Presses a keyboard key + * @param key to press + * @param sleepTime time to wait before and after to press the key + */ + public void pressKey(int key, int sleepTime) { + EmergyaWebDriverUtil.pressKey(key, sleepTime); + } + + /** + * Releases a keyboard key + * @param key to release + * @param sleepTime time to wait before and after to release the key + */ + public void releaseKey(int key, int sleepTime) { + EmergyaWebDriverUtil.releaseKey(key, sleepTime); + } + + /** + * Presses and releases a keyboard key + * @param key to press and release + */ + public void pressReleaseKey(int key) { + EmergyaWebDriverUtil.pressReleaseKey(key); + } + + // **** Mouse events methods section ****// + /** + * Moves the mouse over an element + * @param selector By element + */ + public void moveMouseOverElement(By selector) { + EmergyaWebDriverUtil.moveMouseOverElement(this, selector); + } + + /** + * Moves the mouse out of an element + * @param selector By element + */ + public void moveMouseOutElement(By selector) { + EmergyaWebDriverUtil.moveMouseOutElement(this, selector); + } + + /** + * Clicks with the mouse on an element + * @param selector By element + */ + public void clickOnWithMouse(By selector) { + EmergyaWebDriverUtil.clickOnWithMouse(this, selector); + } + + /** + * Clicks with the mouse out of an element + * @param selector By element + */ + public void clickOutWithMouse(By selector) { + EmergyaWebDriverUtil.clickOutWithMouse(this, selector); + } + + /** + * Double clicks with the mouse on an element + * @param selector By element + */ + public void doubleClickOnWithMouse(By selector) { + EmergyaWebDriverUtil.doubleClickOnWithMouse(this, selector); + + } + + // **** Wait methods section ****// + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element exist in the DOM and false in the opposite case + */ + public boolean wait(By selector, long seconds) { + return EmergyaWebDriverUtil.wait(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is visible in the page and false in the opposite case + */ + public boolean waitUntilVisible(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilVisible(this, selector, seconds); + } + + /** + * It sleeps the driver for X seconds. If the element is clickable in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is clickable in the page and false in the opposite case + */ + public boolean waitUntilElementClickable(By selector, long seconds) { + return EmergyaWebDriverUtil.waitUntilElementClickable(this, selector, + seconds); + } + + /** + * It sleeps the driver for X seconds. If the text is present in element, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @param text to be find + * @return true If the text is present in element, and false in the opposite case + */ + public boolean waitUntilTextPresent(By selector, long seconds, + String text) { + return EmergyaWebDriverUtil.waitUntilTextPresent(this, selector, + seconds, text); + } +} diff --git a/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriver.java b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriver.java new file mode 100644 index 0000000..6a170bf --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriver.java @@ -0,0 +1,187 @@ +package com.emergya.drivers; + +import java.util.List; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +/** + * Emergya custom interface that extends WebDriver + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + */ +public interface EmergyaWebDriver extends WebDriver { + + // **** Basic operation methods section ****// + /** + * Checks if an element exists in the DOM + * @param selector By element + * @return True if the element exists in the DOM and false in the opposite case + */ + public boolean existsElement(By selector); + + /** + * Checks if an element exists in the DOM and is displayed + * @param selector By element + * @return True if the element exists in the DOM and is displayed and false in the opposite case + */ + public boolean isElementDisplayed(By selector); + + /** + * Clicks on an element after wait and if it is displayed + * @param selector By element + */ + public void clickIfExists(By selector); + + // **** Javascript methods section ****// + /** + * Executes JavaScript in the context of the currently window + * @param script The JavaScript to execute + * @return Boolean, Long, String, List, WebElement Or null + */ + public Object executeJavaScript(String script); + + /** + * Puts the focus on an element through its id + * @param driver WebDriver element + * @param id string with the id of an element + */ + public void focus(String id); + + // **** Screenshot methods section ****// + /** + * Saves a screenshot in a path with a timestamp + * @param folderPath to save the screenshot + * @param baseFileName file name + */ + public void saveScreenshotPath(String folderPath, String baseFileName); + + /** + * Saves a screenshot in the default path + * @param driver WebDriver element + */ + public void saveScreenshotDefault(); + + // **** Sleep method ****// + /** + * Stops the execution during some seconds + * @param seconds time to stop the execution + */ + public void sleep(int seconds); + + // **** Keyboard events methods section ****// + /** + * Presses a keyboard key + * @param key to press + * @param sleepTime time to wait before and after to press the key + */ + public void pressKey(int key, int sleepTime); + + /** + * Releases a keyboard key + * @param key to release + * @param sleepTime time to wait before and after to release the key + */ + public void releaseKey(int key, int sleepTime); + + /** + * Presses and releases a keyboard key + * @param key to press and release + */ + public void pressReleaseKey(int key); + + // **** Mouse events methods section ****// + /** + * Moves the mouse over an element + * @param selector By element + */ + public void moveMouseOverElement(By selector); + + /** + * Moves the mouse out of an element + * @param selector By element + */ + public void moveMouseOutElement(By selector); + + /** + * Clicks with the mouse on an element + * @param selector By element + * */ + public void clickOnWithMouse(By selector); + + /** + * Clicks with the mouse out of an element + * @param selector By element + */ + public void clickOutWithMouse(By selector); + + /** + * Double clicks with the mouse on an element + * @param selector By element + */ + public void doubleClickOnWithMouse(By selector); + + // **** Wait methods section ****// + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element exist in the DOM and false in the opposite case + */ + public boolean wait(By selector, long seconds); + + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is visible in the page and false in the opposite case + */ + public boolean waitUntilVisible(By selector, long seconds); + + /** + * It sleeps the driver for X seconds. If the element is clickable in the page, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is clickable in the page and false in the opposite case + */ + public boolean waitUntilElementClickable(By selector, long seconds); + + /** + * It sleeps the driver for X seconds. If the text is present in element, the execution continue without waiting X seconds + * @param selector By element for wait + * @param seconds to be slept + * @param text to be find + * @return true If the text is present in element, and false in the opposite case + */ + public boolean waitUntilTextPresent(By selector, long seconds, String text); + + // **** BasePageObject needed methods section ****// + /** + * Finds elements by xpath + * @param Xpath expression + * @return List of web elements + */ + public List findElementsByXPath(String xpath); + + /** + * Finds element by xpath + * @param Xpath expression + * @return WebElement web element + */ + public WebElement findElementByXPath(String xpath); + + /** + * Find an element by id + * @param id expression + * @return WebElement web element + */ + public WebElement findElementById(String id); + + /** + * Find an element by name + * @param name expression + * @return WebElement web element + */ + public WebElement findElementByName(String name); +} diff --git a/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriverUtil.java b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriverUtil.java new file mode 100644 index 0000000..5cf57f1 --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/drivers/EmergyaWebDriverUtil.java @@ -0,0 +1,620 @@ +package com.emergya.drivers; + +import java.awt.AWTException; +import java.awt.MouseInfo; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.Point; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.TimeoutException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import com.emergya.utils.Initialization; + +/** + * Implements personalized methods to WebDriver + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + */ +public class EmergyaWebDriverUtil { + + private static Logger log = Logger.getLogger(EmergyaWebDriverUtil.class); + + // **** Basic operation methods section ****// + /** + * Checks if an element exists in the DOM + * @param driver WebDriver element + * @param selector By element + * @return True if the element exists in the DOM and false in the opposite case + */ + public static boolean existsElement(EmergyaWebDriver driver, By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start existsElement method"); + + boolean exists = false; + + try { + exists = (driver.findElement(selector) != null); + } catch (Exception ex) { + exists = false; + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End existsElement method"); + + return exists; + } + + /** + * Checks if an element exists in the DOM and is displayed + * @param driver WebDriver element + * @param selector By element + * @return True if the element exists in the DOM and is displayed and false in the opposite case + */ + public static boolean isElementDisplayed(EmergyaWebDriver driver, + By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start isElementDisplayed method"); + + boolean isDisplayed = false; + + try { + WebElement element = driver.findElement(selector); + isDisplayed = (element != null && element.isDisplayed()); + } catch (Exception ex) { + isDisplayed = false; + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End isElementDisplayed method"); + + return isDisplayed; + } + + /** + * Clicks on an element after wait and if it is displayed + * @param driver WebDriver element + * @param selector By element + */ + public static void clickIfExists(EmergyaWebDriver driver, By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start clickIfExists method"); + + wait(driver, selector, 20); + + if (isElementDisplayed(driver, selector)) { + driver.findElement(selector).click(); + } else { + log.error("The element " + selector.toString() + + " is not displayed."); + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End clickIfExists method"); + } + + // **** Javascript methods section ****// + /** + * Executes JavaScript in the context of the currently window + * @param driver WebDriver element + * @param script The JavaScript to execute + * @return Boolean, Long, String, List, WebElement Or null + */ + public static Object executeJavaScript(EmergyaWebDriver driver, + String script) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start executeJavaScript method"); + log.info( + "[log-Utils] EmergyaWebDriverUtil - End executeJavaScript method"); + + return ((JavascriptExecutor) driver).executeScript(script); + } + + /** + * Puts the focus on an element through its id + * @param driver WebDriver element + * @param id string with the id of an element + */ + public static void focus(EmergyaWebDriver driver, String id) { + log.info("[log-Utils] EmergyaWebDriverUtil - Start focus method"); + + driver.executeJavaScript( + "document.getElementById('" + id + "').focus();"); + + log.info("[log-Utils] EmergyaWebDriverUtil - End focus method"); + } + + // **** Screenshot methods section ****// + /** + * Saves a screenshot in a path with a timestamp + * @param driver WebDriver element + * @param folderPath to save the screenshot + * @param baseFileName file name + */ + public static void saveScreenshotPath(EmergyaWebDriver driver, + String folderPath, String baseFileName) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start saveScreenshotPath method"); + + String timeStamp = getTimeStamp(); + File scrFile = ((TakesScreenshot) driver) + .getScreenshotAs(OutputType.FILE); + + try { + FileUtils.copyFile(scrFile, new File(folderPath + File.separator + + baseFileName + "_" + timeStamp + ".png")); + } catch (IOException e) { + log.error("Error creating screenshot", e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End saveScreenshotPath method"); + } + + /** + * Saves a screenshot in the default path + * @param driver WebDriver element + */ + public static void saveScreenshotDefault(EmergyaWebDriver driver) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start saveScreenshotDefault method"); + + String folderPath = Initialization.getInstance().getScreenshotPath(); + + saveScreenshotPath(driver, folderPath, ""); + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End saveScreenshotDefault method"); + } + + // **** Sleep method ****// + /** + * Stops the execution during some seconds + * @param seconds time to stop the execution + */ + public static void sleep(int seconds) { + log.info("[log-Utils] EmergyaWebDriverUtil - Start sleep method"); + + try { + Thread.sleep(seconds * 1000); + } catch (InterruptedException e) { + log.error("A thread has interrupted the current thread", e); + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End sleep method"); + } + + // **** Keyboard events methods section ****// + /** + * Presses a keyboard key + * @param key to press + * @param sleepTime time to wait before and after to press the key + */ + public static void pressKey(int key, int sleepTime) { + log.info("[log-Utils] EmergyaWebDriverUtil - Start pressKey method"); + + Robot r; + + try { + r = new Robot(); + + Thread.sleep(sleepTime * 1000); + r.keyPress(key); + Thread.sleep(sleepTime * 1000); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } catch (InterruptedException e) { + log.error("A thread has interrupted the current thread", e); + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End pressKey method"); + } + + /** + * Releases a keyboard key + * @param key to release + * @param sleepTime time to wait before and after to release the key + */ + public static void releaseKey(int key, int sleepTime) { + log.info("[log-Utils] EmergyaWebDriverUtil - Start releaseKey method"); + + Robot r; + + try { + r = new Robot(); + + Thread.sleep(sleepTime * 1000); + r.keyRelease(key); + Thread.sleep(sleepTime * 1000); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } catch (InterruptedException e) { + log.error("A thread has interrupted the current thread", e); + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End releaseKey method"); + } + + /** + * Presses and releases a keyboard key + * @param key to press and to release + */ + public static void pressReleaseKey(int key) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start pressReleaseKey method"); + + Robot r; + + try { + r = new Robot(); + + r.keyPress(key); + Thread.sleep(500); + r.keyRelease(key); + Thread.sleep(500); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } catch (InterruptedException e) { + log.error("A thread has interrupted the current thread", e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End pressReleaseKey method"); + } + + // **** Mouse events methods section ****// + /** + * Moves the mouse over an element + * @param driver WebDriver element + * @param selector By element + */ + public static void moveMouseOverElement(EmergyaWebDriver driver, + By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start moveMouseOverElement method"); + + Robot r; + + try { + r = new Robot(); + Point point = getPositionToClick(driver, selector); + java.awt.Point location = MouseInfo.getPointerInfo().getLocation(); + + if (((int) location.getX()) != point.getX() + || ((int) location.getY()) != point.getY()) { + r.mouseMove(point.getX(), point.getY()); + driver.sleep(2); + } + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End moveMouseOverElement method"); + } + + /** + * Moves the mouse out of an element + * @param driver WebDriver element + * @param selector By element + */ + public static void moveMouseOutElement(EmergyaWebDriver driver, + By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start moveMouseOutElement method"); + + Robot r; + int x = 0, y = 0; + + try { + r = new Robot(); + + if (existsElement(driver, selector)) { + WebElement element = driver.findElement(selector); + Point position = element.getLocation(); + + x = position.getX() - 10; + y = position.getY() - 10; + } + + Point toMove = new Point(x, y); + java.awt.Point location = MouseInfo.getPointerInfo().getLocation(); + + if (((int) location.getX()) != toMove.getX() + && ((int) location.getY()) != toMove.getY()) { + r.mouseMove(toMove.getX(), toMove.getY()); + driver.sleep(2); + } + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End moveMouseOutElement method"); + } + + /** + * Clicks with the mouse on an element + * @param driver WebDriver element + * @param selector By element + */ + public static void clickOnWithMouse(EmergyaWebDriver driver, By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start clickOnWithMouse method"); + + Robot r; + + try { + r = new Robot(); + + moveMouseOverElement(driver, selector); + + r.mousePress(InputEvent.BUTTON1_MASK); + driver.sleep(1); + r.mouseRelease(InputEvent.BUTTON1_MASK); + driver.sleep(2); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End clickOnWithMouse method"); + } + + /** + * Clicks with the mouse out of an element + * @param driver WebDriver element + * @param selector By element + */ + public static void clickOutWithMouse(EmergyaWebDriver driver, By selector) { + EmergyaWebDriverUtil.moveMouseOutElement(driver, selector); + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start clickOutWithMouse method"); + + try { + Robot r = new Robot(); + + moveMouseOutElement(driver, selector); + + r.mousePress(InputEvent.BUTTON1_MASK); + driver.sleep(1); + r.mouseRelease(InputEvent.BUTTON1_MASK); + driver.sleep(2); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End clickOutWithMouse method"); + } + + /** + * Double clicks with the mouse on an element + * @param driver WebDriver element + * @param selector By element + */ + public static void doubleClickOnWithMouse(EmergyaWebDriver driver, + By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start doubleClickOnWithMouse method"); + + Robot r; + + try { + r = new Robot(); + + moveMouseOverElement(driver, selector); + + r.mousePress(InputEvent.BUTTON1_MASK); + r.mouseRelease(InputEvent.BUTTON1_MASK); + r.mousePress(InputEvent.BUTTON1_MASK); + r.mouseRelease(InputEvent.BUTTON1_MASK); + driver.sleep(2); + } catch (AWTException e) { + log.error( + "The platform configuration does not allow low-level input control", + e); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End doubleClickOnWithMouse method"); + } + + // **** Wait methods section ****// + /** + * It sleeps the driver for X seconds. If the element exist in the DOM, the execution continue without waiting X seconds + * @param driver WebDriver element for sleep + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element exist in the DOM and false in the opposite case + */ + public static boolean wait(EmergyaWebDriver driver, By selector, + long seconds) { + log.info("[log-Utils] EmergyaWebDriverUtil - Start wait method"); + + WebDriverWait w = new WebDriverWait(driver, seconds); + boolean retVal = true; + + try { + w.until(ExpectedConditions.presenceOfElementLocated(selector)); + } catch (TimeoutException e) { + retVal = false; + + log.error("The element: " + selector.toString() + + " is missing in the DOM. Waiting time: " + seconds + + " seconds"); + } + + log.info("[log-Utils] EmergyaWebDriverUtil - End wait method"); + + return retVal; + } + + /** + * It sleeps the driver for X seconds. If the element is visible in the page, the execution continue without waiting X seconds + * @param driver WebDriver element for sleep + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is visible in the page and false in the opposite case + */ + public static boolean waitUntilVisible(EmergyaWebDriver driver, By selector, + long seconds) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start waitUntilVisible method"); + + WebDriverWait w = new WebDriverWait(driver, seconds); + boolean retVal = true; + + try { + w.until(ExpectedConditions.visibilityOfElementLocated(selector)); + } catch (TimeoutException e) { + retVal = false; + + log.error("The element: " + selector.toString() + + " is not visible in the page. Waiting time: " + seconds + + " seconds"); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End waitUntilVisible method"); + + return retVal; + } + + /** + * It sleeps the driver for X seconds. If the element is clickable in the page, the execution continue without waiting X seconds + * @param driver WebDriver element for sleep + * @param selector By element for wait + * @param seconds to be slept + * @return true if the element is clickable in the page and false in the opposite case + */ + public static boolean waitUntilElementClickable(EmergyaWebDriver driver, + By selector, long seconds) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start waitUntilElementClickable method"); + + WebDriverWait w = new WebDriverWait(driver, seconds); + boolean retVal = true; + + try { + w.until(ExpectedConditions.elementToBeClickable(selector)); + } catch (TimeoutException e) { + retVal = false; + + log.error("The element: " + selector.toString() + + " is not clickable. Waiting time: " + seconds + + " seconds"); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End waitUntilElementClickable method"); + + return retVal; + } + + /** + * It sleeps the driver for X seconds. If the text is present in element, the execution continue without waiting X seconds + * @param driver WebDriver element for sleep + * @param selector By element for wait + * @param seconds to be slept + * @param text to be find + * @return true If the text is present in element, and false in the opposite case + */ + public static boolean waitUntilTextPresent(EmergyaWebDriver driver, + By selector, long seconds, String text) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start waitUntilTextPresent method"); + + WebDriverWait w = new WebDriverWait(driver, seconds); + boolean retVal = true; + + try { + w.until(ExpectedConditions.textToBePresentInElementLocated(selector, + text)); + } catch (TimeoutException e) { + retVal = false; + + log.error("The text: " + text + " in the element: " + + selector.toString() + + " is missing in the DOM. Waiting time: " + seconds + + " seconds"); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End waitUntilTextPresent method"); + + return retVal; + } + + // **** Private methods section ****// + /** + * Generates a timestamp + * @return string with a timestamp + */ + private static String getTimeStamp() { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start getTimeStamp method"); + + String timeStamp = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss") + .format(Calendar.getInstance().getTime()); + + log.info("[log-Utils] EmergyaWebDriverUtil - End getTimeStamp method"); + + return timeStamp; + + } + + /** + * Retrieves the center of an element to click it. + * @param driver WebDriver element + * @param selector By element + * @return Point the position of the center of the element + */ + private static Point getPositionToClick(EmergyaWebDriver driver, + By selector) { + log.info( + "[log-Utils] EmergyaWebDriverUtil - Start getPositionToClick method"); + + Point toReturn = null; + int x = 0, y = 0; + + if (existsElement(driver, selector)) { + WebElement element = driver.findElement(selector); + Point position = element.getLocation(); + + x = position.getX() + (element.getSize().getWidth() / 2); + y = position.getY() + (element.getSize().getHeight() / 2); + + toReturn = new Point(x, y); + } + + log.info( + "[log-Utils] EmergyaWebDriverUtil - End getPositionToClick method"); + + return toReturn; + } +} diff --git a/qa_selenium/src/main/java/com/emergya/utils/Initialization.java b/qa_selenium/src/main/java/com/emergya/utils/Initialization.java new file mode 100644 index 0000000..7630dbf --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/utils/Initialization.java @@ -0,0 +1,324 @@ +package com.emergya.utils; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; +import java.util.regex.Matcher; + +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.firefox.FirefoxProfile; + +import com.emergya.drivers.EmergyaChromeDriver; +import com.emergya.drivers.EmergyaFirefoxDriver; +import com.emergya.drivers.EmergyaIEDriver; +import com.emergya.drivers.EmergyaWebDriver; + +/** + * Initializes properties and driver + * @author Jose Antonio Sanchez + */ +public class Initialization { + + private String properties; + private String browser; + private String context; + private String environment; + private String loginURL; + private String os; + private String screenshotPath; + private String videoRecordingPath; + private boolean recordVideo; + private boolean saveVideoForPassed; + private boolean ideEnabled; + private String downloadPath; + private int widthBeforeMaximize; + private int widthAfterMaximize; + private int heightBeforeMaximize; + private int heightAfterMaximize; + private static Initialization instance = null; + private Logger log = Logger.getLogger(Initialization.class); + + EmergyaWebDriver driver; + + /** + * Singleton pattern + * @return a single instance + */ + public static Initialization getInstance() { + if (instance == null) { + instance = new Initialization(); + } + return instance; + } + + /** + * Reads properties when the class is instanced + */ + private Initialization() { + this.readProperties(); + } + + // **** Read properties method ****// + public void readProperties() { + log.info("[log-Properties] " + this.getClass().getName() + + "- Start readProperties test"); + + properties = "test.properties"; + Properties prop = new Properties(); + log = Logger.getLogger(this.getClass()); + + try { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + + // Load a properties file + prop.load(loader.getResourceAsStream(properties)); + + // Get the property value + browser = prop.getProperty("browser"); + context = prop.getProperty("context"); + environment = prop.getProperty("environment"); + loginURL = environment + context; + os = prop.getProperty("OS"); + screenshotPath = prop.getProperty("screenshotPath"); + videoRecordingPath = prop.getProperty("videoRecordingPath", + this.screenshotPath); + recordVideo = "true".equals( + prop.getProperty("activateVideoRecording", "false")); + saveVideoForPassed = "true" + .equals(prop.getProperty("saveVideoForPassed", "false")); + ideEnabled = "true".equals(prop.getProperty("ideEnabled", "false")); + + // Generate download path + downloadPath = ""; + + String auxPath = this.getClass().getProtectionDomain() + .getCodeSource().getLocation().getFile(); + + String[] arrayPath = auxPath.split("/"); + + if (auxPath.startsWith(File.separator)) { + downloadPath = File.separator; + } + + for (int i = 1; i < arrayPath.length; i++) { + downloadPath = downloadPath + arrayPath[i] + "/"; + } + + downloadPath = downloadPath.replace("target/classes/", + prop.getProperty("downloadPath")); + + downloadPath = downloadPath.replaceAll("/", + Matcher.quoteReplacement(File.separator)); + + if (!downloadPath + .endsWith(Matcher.quoteReplacement(File.separator))) { + downloadPath += Matcher.quoteReplacement(File.separator); + } + + File file = new File(this.getDownloadPath()); + if (!file.exists()) { + file.mkdir(); + } + + log.info("Auto detected operative System = " + os); + } catch (IOException ex) { + log.error( + "test.properties file is not found. If this is the first time you excuted your test you can copy the settings properties file in the test folder in svn and customized it to match your environment"); + } + + log.info("[log-Properties] " + this.getClass().getName() + + "- End readProperties test"); + } + + // **** Driver initialization method ****// + public EmergyaWebDriver initialize() { + log.info("[log-Properties] " + this.getClass().getName() + + "- Start initialize test"); + + EmergyaWebDriver tmpDriver = null; + + // Driver initialization + if (browser.equalsIgnoreCase("Firefox")) { + FirefoxProfile firefoxProfile = new FirefoxProfile(); + + firefoxProfile.setPreference( + "browser.download.manager.focusWhenStarting", true); + firefoxProfile.setEnableNativeEvents(true); + firefoxProfile.setPreference("browser.download.folderList", 2); + firefoxProfile.setPreference( + "browser.download.manager.showWhenStarting", false); + firefoxProfile.setPreference("browser.download.dir", + this.getDownloadPath()); + + File dir = new File(this.getDownloadPath()); + if (dir.isDirectory()) { + File[] files = dir.listFiles(); + + for (File file : files) { + if (file.isFile()) { + file.delete(); + } + } + } + + firefoxProfile.setPreference( + "browser.helperApps.neverAsk.saveToDisk", + "application/x-jar,application/application/vnd.android.package-archive," + + "application/msword,application/x-rar-compressed,application/octet-stream," + + "application/csv, application/excel, application/vnd.ms-excel,application/x-excel, application/x-msexcel,text/csv," + + "image/jpeg, application/zip, video/x-msvideo, image/png, application/pdf, text/xml, text/html"); + firefoxProfile.setPreference("pdfjs.disabled", true); + + tmpDriver = new EmergyaFirefoxDriver(firefoxProfile); + + } else if (browser.equalsIgnoreCase("Chrome")) { + ChromeOptions options = new ChromeOptions(); + options.addArguments("--start-maximized"); + + if (os.equalsIgnoreCase("windows")) { + System.setProperty("webdriver.chrome.driver", + "files/software/chromedriver.exe"); + } else { + System.setProperty("webdriver.chrome.driver", + "files/software/chromedriver"); + } + + tmpDriver = new EmergyaChromeDriver(options); + } else if (browser.equalsIgnoreCase("IE") + && os.equalsIgnoreCase("windows")) { + System.setProperty("webdriver.ie.driver", + "files/software/IEDriverServer.exe"); + tmpDriver = new EmergyaIEDriver(); + } + + // Common functions + driver = tmpDriver; + + log.info("Browser initialized with dimensions: " + + driver.manage().window().getSize().getWidth() + "px X " + + driver.manage().window().getSize().getHeight() + "px"); + + widthBeforeMaximize = driver.manage().window().getSize().getWidth(); + heightBeforeMaximize = driver.manage().window().getSize().getHeight(); + + driver.get(loginURL); + + tmpDriver.findElement(By.tagName("body")).sendKeys(Keys.F11); + + driver.sleep(1); + + widthAfterMaximize = driver.manage().window().getSize().getWidth(); + heightAfterMaximize = driver.manage().window().getSize().getHeight(); + + if ((widthBeforeMaximize == widthAfterMaximize) + && (heightBeforeMaximize == heightAfterMaximize)) { + log.info("Not maximized first time...try again"); + + driver.sleep(1); + + tmpDriver.findElement(By.tagName("body")).sendKeys(Keys.F11); + + driver.sleep(2); + } + + this.cleanDownloadDirectory(); + + log.info("Browser resized with dimensions: " + + driver.manage().window().getSize().getWidth() + "px X " + + driver.manage().window().getSize().getHeight() + "px"); + + log.info("[log-Properties] " + this.getClass().getName() + + "- End initialize test"); + + return driver; + } + + // **** Getters methods section ****// + public String getBrowser() { + return browser; + } + + public String getContext() { + return context; + } + + public String getEnvironment() { + return environment; + } + + public String getLoginURL() { + return loginURL; + } + + public String getOS() { + return os; + } + + public String getScreenshotPath() { + return this.screenshotPath; + } + + public String getVideoRecordingPath() { + return videoRecordingPath; + } + + public boolean isRecordVideo() { + return recordVideo; + } + + public boolean isSaveVideoForPassed() { + return saveVideoForPassed; + } + + public boolean isIDEEnabled() { + return ideEnabled; + } + + public String getDownloadPath() { + return downloadPath; + } + + // **** Download methods section ****// + /** + * Returns the donwloaded filepath + * @param filename the name of the file + * @return the donwloaded filepath + */ + public String getDownloadedFilePath(String filename) { + String path = this.getDownloadPath() + filename; + File f = new File(path); + if (f.exists()) { + return path; + } else { + log.info("Not exists the file"); + return null; + } + } + + /** + * Cleans the download directory. + */ + public void cleanDownloadDirectory() { + File f = new File(this.getDownloadPath()); + if (f.exists() && f.isDirectory()) { + try { + FileUtils.cleanDirectory(f); + } catch (IOException e) { + log.error(e.getStackTrace()); + } + } + } + + /** + * Checks if the directory is empty. + * @return true is it's empty + */ + public boolean isEmptyDownloadDirectory() { + File f = new File(this.getDownloadPath()); + return f.exists() && f.isDirectory() && f.list().length == 0; + } +} diff --git a/qa_selenium/src/main/java/com/emergya/utils/PropertiesHandler.java b/qa_selenium/src/main/java/com/emergya/utils/PropertiesHandler.java new file mode 100644 index 0000000..dfbb4b6 --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/utils/PropertiesHandler.java @@ -0,0 +1,199 @@ +package com.emergya.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.log4j.Logger; + +/** + * Class to read the properties files + * @author Alejandro Gomez + * @contributor Ivan Bermudez + */ +public class PropertiesHandler { + + /** + * Logger class initialization. + */ + private static final Logger log = Logger.getLogger(PropertiesHandler.class); + + /** + * Properties cache. + */ + private Map properties; + + /** + * Instance of the PropertiesHandler class. + */ + private static PropertiesHandler instance = null; + + /** + * Attribute to have control about which is the last read file. + */ + private String lastReadFile; + + /** + * Default constructor. + */ + private PropertiesHandler() { + this.properties = new HashMap(); + this.lastReadFile = null; + } + + /** + * Returns an instance of the PropertiesHanler. + * @return PropertiesHandler instance. + */ + public static PropertiesHandler getInstance() { + // singleton pattern + if (instance == null) { + instance = new PropertiesHandler(); + } + return instance; + } + + /** + * Loads a properties file with the given filename. + * @param filename of the properties file to read or the path to the file. + * @return true/false if was read successfully. + */ + public boolean load(String filename) { + log.info("Reading properties from the file: " + filename); + boolean read = false; + // If it wasn't read previously + if (!this.properties.containsKey(filename)) { + log.info("There is no cached properties, reading them now from " + + filename); + this.lastReadFile = null; + InputStream inputStream = getInputStream(filename); + // if the file was loaded + if (inputStream != null) { + Properties propertiesFile = new Properties(); + try { + propertiesFile.load(inputStream); + // add the readed file into the cache + this.properties.put(filename, propertiesFile); + this.lastReadFile = filename; + read = true; + log.info(filename + " read and cached successfully!"); + } catch (IOException ex) { + log.error("An error occured reading properties from " + + filename + ": " + ex); + } + } else { + log.warn("Couldn't read properties from " + filename + + ". It seems the file doesn't exist"); + } + } else { + read = true; + this.lastReadFile = filename; + log.info( + "Properties were cached, so we don't have to read anything"); + } + return read; + } + + /** + * Returns an InputStream from a filename or file path. + * @param filename of the properties file to read or the path to the file. + * @return InputStream object. + */ + private InputStream getInputStream(String filename) { + log.info("Getting the inputStream for the filename " + filename); + // checking if it's a full path + File f = new File(propertyFileAbsolutePath(filename)); + InputStream inputStream = null; + if (f.exists() && !f.isDirectory()) { + log.info("It's a full path, and the file exists"); + try { + inputStream = new FileInputStream(f); + } catch (FileNotFoundException ex) { + log.error("The file was found BUT couldn't be loaded: " + ex); + } + } else { + log.info("Reading the file from the context"); + ClassLoader classLoader = Thread.currentThread() + .getContextClassLoader(); + inputStream = classLoader.getResourceAsStream(filename); + } + return inputStream; + } + + private String propertyFileAbsolutePath(String filename) { + String absoluteFileName = filename; + log.info("Checking configuration from absoluth path " + + absoluteFileName); + File f = new File(absoluteFileName); + if (f.exists() && !f.isDirectory()) { + return absoluteFileName; + } + + return filename; + } + + /** + * Retrieves the value of a given property. + * @param propertyName to read. + * @return value of the property or null if it doesn't exist. + */ + public String get(String propertyName) { + String value = null; + // return the key just if the file was loaded previously and if the + // Properties object exists + if (this.lastReadFile != null + && this.properties.containsKey(this.lastReadFile)) { + value = this.properties.get(this.lastReadFile) + .getProperty(propertyName); + } + return value; + } + + /** + * Refreshes all the loaded files reading them again. + * If a file doesn't exist now, it will not be refreshed. + */ + public void refreshLoadedFiles() { + log.info("Refreshing " + this.properties.size() + + " cached properties files"); + for (String filename : this.properties.keySet()) { + Properties oldProperties = this.properties.get(filename); + // removing the old Properties object to force reload it. + this.properties.remove(filename); + // if an error occurred, we put again the old properties + if (!this.load(filename)) { + log.error("An error occurred refreshing the " + filename + + " file. The old properties will be used again!"); + this.properties.put(filename, oldProperties); + } else { + log.info(filename + " refreshed successfully!"); + } + + } + } + + /** + * Refreshes a given property file. + * @param fileName to read. + * If a file doesn't exist now, it will not be refreshed. + */ + public void refreshPropertyFile(String fileName) { + log.info("Refreshing " + fileName + " cached property file"); + Properties oldProperties = this.properties.get(fileName); + // removing the old Properties object to force reload it. + this.properties.remove(fileName); + // if an error occurred, we put again the old properties + if (!this.load(fileName)) { + log.error("An error occurred refreshing the " + fileName + + " file. The old properties will be used again!"); + this.properties.put(fileName, oldProperties); + } else { + log.info(fileName + " refreshed successfully!"); + } + } +} diff --git a/qa_selenium/src/main/java/com/emergya/utils/StringFormatter.java b/qa_selenium/src/main/java/com/emergya/utils/StringFormatter.java new file mode 100644 index 0000000..51f6822 --- /dev/null +++ b/qa_selenium/src/main/java/com/emergya/utils/StringFormatter.java @@ -0,0 +1,137 @@ +package com.emergya.utils; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +/** + * Class to format text + * @author Alejandro Gomez + */ +public class StringFormatter { + + /** + * Escape strings with ' for xpath expression + * @param originalString + * @return escaped string + */ + public static String escapeSimpleQuotesForXpath(String originalString) { + return escapeQuotesForXpath(originalString, "'"); + } + + /** + * Escape strings with " for xpath expression + * @param originalString + * @return escaped string + */ + public static String escapeDoubleQuotesForXpath(String originalString) { + return escapeQuotesForXpath(originalString, "\""); + } + + /** + * Escape strings with " or ' for xpath expression + * @param originalString + * @return escaped string + */ + private static String escapeQuotesForXpath(String originalString, + String quote) { + String formattedString = ""; + if (StringUtils.isNotBlank(originalString) + && StringUtils.isNotBlank(quote)) { + String xpathDelimitter = "'"; + String xpathDelimiterForQuote; + if (quote.equals("\"")) { + xpathDelimiterForQuote = "'"; + } else { + xpathDelimiterForQuote = "\""; + } + + if (originalString.startsWith(quote)) { + formattedString += xpathDelimiterForQuote + quote + + xpathDelimiterForQuote; + formattedString += ","; + } + String[] parts = originalString.split(quote); + if (parts.length > 1) { + for (int i = 0; i < parts.length; i++) { + formattedString += xpathDelimitter + parts[i] + + xpathDelimitter; + if (i < parts.length - 1) { + formattedString += ","; + formattedString += xpathDelimiterForQuote + quote + + xpathDelimiterForQuote; + formattedString += ","; + } + } + if (originalString.endsWith(quote)) { + formattedString += ","; + formattedString += xpathDelimiterForQuote + quote + + xpathDelimiterForQuote; + } + formattedString = "concat(" + formattedString + ")"; + } else { + formattedString = xpathDelimitter + originalString + + xpathDelimitter; + } + } + return formattedString; + } + + /** + * Method to get a random string and different from other. + * @param stringToBeDifferent string we want to have another different. + * @return a different random string. + */ + public static String getARandomAndDifferentStringOf( + String stringToBeDifferent) { + StringBuffer buffer = new StringBuffer(); + String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + if (StringUtils.isNotBlank(stringToBeDifferent)) { + do { + for (int i = 0; i < stringToBeDifferent.length(); i++) { + double index = Math.random() * characters.length(); + buffer.append(characters.charAt((int) index)); + } + } while (buffer.toString().equalsIgnoreCase(stringToBeDifferent)); + } + return buffer.toString(); + } + + /** + * Method to get a random string and different from others. + * @param stringToBeDifferent string we want to have another different. + * @return a different random string. + */ + public static String getARandomAndDifferentStringOf( + List stringsToBeDifferent) { + + StringBuffer buffer = new StringBuffer(); + String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + if (!stringsToBeDifferent.isEmpty()) { + do { + for (int i = 0; i < stringsToBeDifferent.get(0).length(); i++) { + double index = Math.random() * characters.length(); + buffer.append(characters.charAt((int) index)); + } + } while (stringsToBeDifferent.contains(buffer.toString())); + } + return buffer.toString(); + } + + /** + * Method to get a random string with a lenght. + * @param length string length + * @return a random string. + */ + public static String getARandomWithALenght(int length) { + StringBuffer buffer = new StringBuffer(); + String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + + for (int i = 0; i < length; i++) { + double index = Math.random() * characters.length(); + buffer.append(characters.charAt((int) index)); + } + + return buffer.toString(); + } +} diff --git a/qa_selenium/src/test/java/com/emergya/pageObjects/AdministrationMainPage.java b/qa_selenium/src/test/java/com/emergya/pageObjects/AdministrationMainPage.java new file mode 100644 index 0000000..b145eac --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/pageObjects/AdministrationMainPage.java @@ -0,0 +1,308 @@ +package com.emergya.pageObjects; + +import org.apache.log4j.Logger; +import org.openqa.selenium.By; + +import com.emergya.drivers.EmergyaWebDriver; + +public class AdministrationMainPage extends BasePageObject { + /** + * Logger class initialization. + */ + Logger log = Logger.getLogger(GoogleMainPage.class); + + /** + * Constructor method + * @param driver selenium webdriver + */ + public AdministrationMainPage(EmergyaWebDriver driver) { + super(driver); + this.isReady(); + } + + /** + * Checks that the PO is ready + * @param pageObject page object to be used + */ + @Override + public boolean isReady() { + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - Start isReady method"); + + boolean status = this.isElementVisibleByXPath("imgLogo"); + + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - End isReady method"); + + return status; + + } + + // Page object methods + /** + * This method do a search in google by a string search + * @param stringSearch + */ + public void doSearch() { + log.info("[log-" + this.getClass().getSimpleName() + + "]- Start doSearch -[" + this.getClass().getSimpleName() + + "- method]"); + + String userField = "admin"; + String passField = "proyecto"; + boolean a = false; + boolean b = false; + + if (this.isElementVisibleById("userField")) { + this.getElementById("userField").sendKeys(userField); + a = true; + } + ; + if (this.isElementVisibleById("passField")) { + this.getElementById("passField").sendKeys(passField); + b = true; + } + ; + if (a && b) { + if (this.isElementVisibleByXPath("sessionButton")) { + this.getElementByXPath("sessionButton").click(); + } + ; + } + ; + log.info( + "[log-" + this.getClass().getSimpleName() + "]- End doSearch -[" + + this.getClass().getSimpleName() + "- method]"); + }; + + /** + * This method insert a new news + * @param stringSearch + */ + public void addNew() { + log.info( + "[log-" + this.getClass().getSimpleName() + "]- Start addNew -[" + + this.getClass().getSimpleName() + "- method]"); + + String titleField = "hola"; + String descriptionField = "hola"; + boolean a = false; + boolean b = false; + boolean c = false; + boolean d = false; + + if (this.isElementVisibleById("titlenewsfield")) { + this.getElementById("titlenewsfield").sendKeys(titleField); + a = true; + } + ; + if (this.isElementVisibleById("descriptionnews")) { + this.getElementById("descriptionnews").sendKeys(descriptionField); + b = true; + } + ; + if (this.isElementVisibleByXPath("datenews")) { + this.getElementByXPath("datenews").click(); + c = true; + } + ; + + if (this.isElementVisibleByXPath("timenews")) { + this.getElementByXPath("timenews").click(); + d = true; + } + ; + + if (a && b && c && d) { + if (this.isElementVisibleByXPath("savenewsbutton")) { + this.getElementByXPath("savenewsbutton").click(); + } + ; + } + ; + log.info("[log-" + this.getClass().getSimpleName() + "]- End addNew -[" + + this.getClass().getSimpleName() + "- method]"); + }; + + /** + * This method do a search in google by a string search + * @param stringSearch + */ + public void deleteNew() { + log.info("[log-" + this.getClass().getSimpleName() + + "]- Start deleteNew -[" + this.getClass().getSimpleName() + + "- method]"); + + if (this.isElementVisibleByXPath("selectnews")) { + this.getElementByXPath("selectnews").click(); + } + if (this.isElementVisibleByXPath("selectdelete")) { + this.getElementByXPath("selectdelete").click(); + } + if (this.isElementVisibleByXPath("deletenews")) { + this.getElementByXPath("deletenews").click(); + } + ; + if (this.isElementVisibleByXPath("confirmdelete")) { + this.getElementByXPath("confirmdelete").click(); + } + ; + + log.info("[log-" + this.getClass().getSimpleName() + + "]- End deleteNew -[" + this.getClass().getSimpleName() + + "- method]"); + }; + + public void goAdmin() { + driver.get("localhost:8000/admin"); + }; + + /** + * This method insert a new news + * @param stringSearch + */ + public void addEvent() { + log.info("[log-" + this.getClass().getSimpleName() + + "]- Start addEvent -[" + this.getClass().getSimpleName() + + "- method]"); + + String titleField = "hola"; + String descriptionField = "hola"; + boolean a = false; + boolean b = false; + boolean c = false; + boolean d = false; + boolean e = false; + boolean f = false; + + if (this.isElementVisibleById("titleeventfield")) { + this.getElementById("titleeventfield").sendKeys(titleField); + a = true; + } + ; + if (this.isElementVisibleById("descriptionevent")) { + this.getElementById("descriptionevent").sendKeys(descriptionField); + b = true; + } + ; + if (this.isElementVisibleByXPath("dateeventstart")) { + this.getElementByXPath("dateeventstart").click(); + c = true; + } + ; + + if (this.isElementVisibleByXPath("timeeventstart")) { + this.getElementByXPath("timeeventstart").click(); + d = true; + } + ; + if (this.isElementVisibleByXPath("dateeventend")) { + this.getElementByXPath("dateeventend").click(); + e = true; + } + ; + if (this.isElementVisibleByXPath("timeeventend")) { + this.getElementByXPath("timeeventend").click(); + f = true; + } + ; + + if (a && b && c && d && e && f) { + if (this.isElementVisibleByXPath("saveeventbutton")) { + this.getElementByXPath("saveeventbutton").click(); + } + ; + } + ; + log.info( + "[log-" + this.getClass().getSimpleName() + "]- End addEvent -[" + + this.getClass().getSimpleName() + "- method]"); + }; + + /** + * This method do a search in google by a string search + * @param stringSearch + */ + public void deleteEvent() { + log.info("[log-" + this.getClass().getSimpleName() + + "]- Start deleteEvent -[" + this.getClass().getSimpleName() + + "- method]"); + + if (this.isElementVisibleByXPath("selectevent")) { + this.getElementByXPath("selectevent").click(); + } + if (this.isElementVisibleByXPath("selectdeleteevent")) { + this.getElementByXPath("selectdeleteevent").click(); + } + if (this.isElementVisibleByXPath("deleteevent")) { + this.getElementByXPath("deleteevent").click(); + } + ; + if (this.isElementVisibleByXPath("confirmdeleteevent")) { + this.getElementByXPath("confirmdeleteevent").click(); + } + ; + + log.info("[log-" + this.getClass().getSimpleName() + + "]- End deleteEvent -[" + this.getClass().getSimpleName() + + "- method]"); + }; + + /* + * This method do click to access to the admin main page. + */ + public AdministrationMainPage clickOnSessionAdministrationPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='login-form']/div[3]/input"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new AdministrationMainPage(driver); + }; + + public AdministrationMainPage clickOnNewsAdministrationPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='content-main']/div[2]/table/tbody/tr[2]/th/a"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new AdministrationMainPage(driver); + }; + + public AdministrationMainPage clickOnAddNewsAdministrationPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='content-main']/ul/li/a"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new AdministrationMainPage(driver); + }; + + public AdministrationMainPage clickOnEventAdministrationPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='content-main']/div[2]/table/tbody/tr[1]/th/a"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new AdministrationMainPage(driver); + }; + + public AdministrationMainPage clickOnAddEventAdministrationPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='content-main']/ul/li/a"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new AdministrationMainPage(driver); + }; +} diff --git a/qa_selenium/src/test/java/com/emergya/pageObjects/BasePageObject.java b/qa_selenium/src/test/java/com/emergya/pageObjects/BasePageObject.java new file mode 100644 index 0000000..539fad0 --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/pageObjects/BasePageObject.java @@ -0,0 +1,284 @@ +package com.emergya.pageObjects; + +import java.io.File; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.emergya.drivers.EmergyaWebDriver; +import com.emergya.utils.Initialization; +import com.emergya.utils.PropertiesHandler; + +/** + * Class to group the common features of all PO's + * @author Jose Antonio Sanchez + * @author Alejandro Gomez + * @author Ivan Bermudez + */ +public abstract class BasePageObject { + + protected final EmergyaWebDriver driver; + protected Initialization config = Initialization.getInstance(); + protected String className = ""; + + static Logger log = Logger.getLogger(BasePageObject.class); + + public BasePageObject(EmergyaWebDriver driver) { + this.driver = driver; + this.className = getClass().getSimpleName(); + } + + /** + * TIMEOUT for elements. + */ + protected static final long TIMEOUT = 20; // Seconds + + /** + * This method builds the file selector path for each Page Object + * @return the file selectors path. + */ + protected String getSelectorsFilePath() { + String filePath = "selectors" + File.separatorChar; + String baseName = this.className.toLowerCase(); + filePath += baseName + ".properties"; + return filePath; + } + + /** + * Checks that the PO is ready + * @param pageObject page object to be used + */ + public abstract boolean isReady(); + + // **** ID methods section ****// + /** + * This method interacts with Selenium to retrieve the needed element. By ID + * @param key of the item to be selected. In the related selector file should exists an entry with: key.type and key.id + * @return the selected {@link Webelement} object + */ + public WebElement getElementById(String key) { + WebElement element = null; + PropertiesHandler handler = PropertiesHandler.getInstance(); + handler.load(this.getSelectorsFilePath()); + String type = handler.get(key + ".type"); // Could be null + String id = handler.get(key + ".id"); // getElementByIdJustId + + if (type == null && StringUtils.isNotBlank(id)) { + element = this.getElementByIdJustId(id); + } else { + if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(id)) { + element = this.getElementById(type, id); + } else { + log.error("Trying to retrieve from " + + this.getSelectorsFilePath() + + " file the item with the key " + key + " but " + key + + ".type and/or " + key + ".id are missing!"); + } + } + return element; + } + + /** + * This method checks if a {@link WebElement} is displayed and visible for selenium. By ID + * @param key of the item to be selected. In the related selector file should exists an entry with: key.type and key.id + * @return true if the element exists and it's visible. + */ + public boolean isElementVisibleById(String key) { + boolean showed = false; + WebElement element = this.getElementById(key); + if (isVisible(element)) { + showed = true; + } + return showed; + } + + // **** Name methods section ****// + /** + * This method interacts with Selenium to retrieve the needed element. By Name + * @param key of the item to be selected. In the related selector file should exists an entry with: key.type and key.name + * @return the selected {@link Webelement} object + */ + public WebElement getElementByName(String key) { + WebElement element = null; + PropertiesHandler handler = PropertiesHandler.getInstance(); + handler.load(this.getSelectorsFilePath()); + String type = handler.get(key + ".type"); // Could be null + String name = handler.get(key + ".name"); // getElementByNameJustName + + if (type == null && StringUtils.isNotBlank(name)) { + element = this.getElementByNameJustName(name); + } else { + if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(name)) { + element = this.getElementByName(type, name); + } else { + log.error("Trying to retrieve from " + + this.getSelectorsFilePath() + + " file the item with the key " + key + " but " + key + + ".type and/or " + key + ".name are missing!"); + } + } + return element; + } + + /** + * This method checks if a {@link WebElement} is displayed and visible for selenium. By Name + * @param key of the item to be selected. In the related selector file should exists an entry with: key.type and key.name + * @return true if the element exists and it's visible. + */ + public boolean isElementVisibleByName(String key) { + boolean showed = false; + WebElement element = this.getElementByName(key); + if (isVisible(element)) { + showed = true; + } + return showed; + } + + + // **** XPath methods section ****// + /** + * This method interacts with selenium to retrieve the needed element. By xpath + * @param key of the item to be selected. In the related selector file should exists an entry with: key.xpath + * @return the selected {@link WebElement} object. + */ + public WebElement getElementByXPath(String key) { + WebElement element = null; + PropertiesHandler handler = PropertiesHandler.getInstance(); + handler.load(this.getSelectorsFilePath()); + String xpath = handler.get(key + ".xpath"); + + if (StringUtils.isNotBlank(xpath)) { + element = this.getElementByXpath(xpath); + } else { + log.error("Trying to retrieve from " + this.getSelectorsFilePath() + + " file the item with the key " + key + " but " + key + + ".xpath is missing!"); + } + return element; + } + + /** + * This method interacts with selenium to retrieve the list of needed element. By xpath + * @param key of the items to be selected. In the related selector file should exists an entry with: key.xpath + * @return a List of the selected {@link WebElement} object + */ + public List getElementsByXPath(String key) { + List element = null; + PropertiesHandler handler = PropertiesHandler.getInstance(); + handler.load(this.getSelectorsFilePath()); + String xpath = handler.get(key + ".xpath"); + + if (StringUtils.isNotBlank(xpath)) { + element = this.getElementsByXpath(xpath); + } else { + log.error("Trying to retrieve from " + this.getSelectorsFilePath() + + " file the item(s) with the key " + key + " but " + key + + ".xpath is missing!"); + } + return element; + } + + /** + * This method checks if a {@link WebElement} is displayed and visible for selenium. By xpath + * @param xpath of the item to be selected. In the related selector file should exists an entry with and key.xpath + * @return true if the element exists and it's visible + */ + public boolean isElementVisibleByXPath(String key) { + boolean showed = false; + WebElement element = this.getElementByXPath(key); + if (element != null) { + showed = true; + } + return showed; + } + + // **** Private methods section ****// + /** + * This method interacts with selenium to retrieve the needed element by ID (just with ID) + * @param id of the element to be retrieved + * @return the built id selector. + */ + private WebElement getElementByIdJustId(String id) { + this.driver.wait(By.id(id), TIMEOUT); + return this.driver.findElementById(id); + } + + /** + * This method interacts with selenium to retrieve the needed element by ID + * @param type of the element to be retrieved + * @param id of the element to be retrieved + * @return the built id selector + */ + private WebElement getElementById(String type, String id) { + this.driver.wait(By.id(this.buildIdSelector(type, id)), TIMEOUT); + return this.driver.findElementById(this.buildIdSelector(type, id)); + } + + /** + * This method interacts with selenium to retrieve the needed element by Name (just with Name) + * @param id of the element to be retrieved + * @return the built name selector. + */ + private WebElement getElementByNameJustName(String name) { + this.driver.wait(By.name(name), TIMEOUT); + return this.driver.findElementByName(name); + } + + /** + * This method interacts with selenium to retrieve the needed element by Name + * @param type of the element to be retrieved + * @param name of the element to be retrieved + * @return the built name selector + */ + private WebElement getElementByName(String type, String name) { + this.driver.wait(By.name(this.buildIdSelector(type, name)), TIMEOUT); + return this.driver.findElementByName(this.buildIdSelector(type, name)); + } + + /** + * This method interacts with selenium to retrieve the needed element by xpath + * @param xpath of the element to be retrieved + * @return the built xpath selector. + */ + private WebElement getElementByXpath(String xpath) { + this.driver.wait(By.xpath(xpath), TIMEOUT); + return this.driver.findElementsByXPath(xpath).get(0); + } + + /** + * This method interacts with selenium to retrieve the needed elements by xpath + * @param xpath of the elements to be retrieved + * @return the built xpath list. + */ + private List getElementsByXpath(String xpath) { + this.driver.wait(By.xpath(xpath), TIMEOUT); + return this.driver.findElementsByXPath(xpath); + } + + /** + * It checks if an element is visible for selenium + * @param element to be checked + * @return if is showed the element + */ + private boolean isVisible(WebElement element) { + boolean showed = false; + if (element != null && element.isDisplayed()) { + showed = true; + } + return showed; + } + + /** + * This method builds the id selector using the UI logic + * @param type of the element to be retrieved + * @param id of the element to be retrieved + * @return the built id selector + */ + private String buildIdSelector(String type, String id) { + String buttonSelector = type + "-" + id; + return buttonSelector; + } +} diff --git a/qa_selenium/src/test/java/com/emergya/pageObjects/EmergyaMainPage.java b/qa_selenium/src/test/java/com/emergya/pageObjects/EmergyaMainPage.java new file mode 100644 index 0000000..c560e5c --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/pageObjects/EmergyaMainPage.java @@ -0,0 +1,75 @@ +package com.emergya.pageObjects; + +import org.apache.log4j.Logger; +import org.openqa.selenium.By; + +import com.emergya.drivers.EmergyaWebDriver; + +/** + * A Page Object (PO) contain the behavior of a specific page in the application + * EmergyaMainPage: This PO contain the methods to interact with the emergya main page + * @author Ivan Bermudez + * @author Jose Antonio Sanchez + */ +public class EmergyaMainPage extends BasePageObject { + + /** + * Logger class initialization. + */ + Logger log = Logger.getLogger(GoogleMainPage.class); + + /** + * Constructor method + * @param driver selenium webdriver + */ + public EmergyaMainPage(EmergyaWebDriver driver) { + super(driver); + this.isReady(); + } + + /** + * Checks that the PO is ready + * @param pageObject page object to be used + */ + @Override + public boolean isReady() { + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - Start isReady method"); + + boolean status = this.isElementVisibleByXPath("imgLogoEmergya"); + + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - End isReady method"); + + return status; + } + + // Page object methods + /* + * This method search contact tab on Emergya main page. + */ + public EmergyaMainPage clickOnContactEmergyaPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='block-menu-menu-cabecera']/ul/li[3]/a/span"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new EmergyaMainPage(driver); + } + + /* + * This method search Work with us in contact Emergya main page. + */ + public EmergyaMainPage clickOnWorkEmergyaPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xPathSelector = ".//*[@id='block-menu-menu-cabecera']/ul/li[1]/a/span"; + driver.clickIfExists(By.xpath(xPathSelector)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new EmergyaMainPage(driver); + } +} diff --git a/qa_selenium/src/test/java/com/emergya/pageObjects/GoogleMainPage.java b/qa_selenium/src/test/java/com/emergya/pageObjects/GoogleMainPage.java new file mode 100644 index 0000000..f28938a --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/pageObjects/GoogleMainPage.java @@ -0,0 +1,88 @@ +package com.emergya.pageObjects; + +import org.apache.log4j.Logger; +import org.openqa.selenium.By; + +import com.emergya.drivers.EmergyaWebDriver; + +/** + * A Page Object (PO) contain the behavior of a specific page in the application + * GoogleMainPage: This PO contain the methods to interact with the google main page + * @author Jose Antonio Sanchez + * @author Ivan Bermudez + */ +public class GoogleMainPage extends BasePageObject { + + /** + * Logger class initialization. + */ + Logger log = Logger.getLogger(GoogleMainPage.class); + + /** + * Constructor method + * @param driver selenium webdriver + */ + public GoogleMainPage(EmergyaWebDriver driver) { + super(driver); + this.isReady(); + } + + /** + * Checks that the PO is ready + * @param pageObject page object to be used + */ + @Override + public boolean isReady() { + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - Start isReady method"); + + boolean status = this.isElementVisibleById("imgLogo"); + + log.info("[log-PageObjects] " + this.getClass().getSimpleName() + + " - End isReady method"); + + return status; + } + + // Page object methods + /** + * This method do a search in google by a string search + * @param stringSearch + */ + public void doSearch(String stringSearch) { + log.info("[log-" + this.getClass().getSimpleName() + + "]- Start doSearch -[" + this.getClass().getSimpleName() + + "- method]"); + + String keyField = "searchField"; + String keySmallButtonSearch = "smallSearchButton"; + + if (this.isElementVisibleById(keyField)) { + this.getElementById(keyField).sendKeys(stringSearch); + + if (this.isElementVisibleById(keySmallButtonSearch)) { + this.getElementById(keySmallButtonSearch).click(); + } + } + + log.info( + "[log-" + this.getClass().getSimpleName() + "]- End doSearch -[" + + this.getClass().getSimpleName() + "- method]"); + } + + /** + * This method click on Emergya page + * @return + */ + public EmergyaMainPage clickOnEmergyaPage() { + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- Start clickOnPage method"); + String xpathLink = "//h3[@class='r']/a[contains(@href,'emergya.es')]"; + + driver.clickIfExists(By.xpath(xpathLink)); + + log.info("[log-pageObjects]" + this.getClass().getSimpleName() + + "]- End clickOnPage method"); + return new EmergyaMainPage(driver); + } +} \ No newline at end of file diff --git a/qa_selenium/src/test/java/com/emergya/testSets/AdministrationTestSet.java b/qa_selenium/src/test/java/com/emergya/testSets/AdministrationTestSet.java new file mode 100644 index 0000000..26a4bfc --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/testSets/AdministrationTestSet.java @@ -0,0 +1,411 @@ +package com.emergya.testSets; + +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.emergya.pageObjects.AdministrationMainPage; +import com.emergya.utils.DefaultTestSet; + +/** + * A test class contain the tests of a specific page in the application + * @author Jose Antonio Sanchez + * @author Ivan Bermudez + */ +public class AdministrationTestSet extends DefaultTestSet { + + Logger log = Logger.getLogger(AdministrationTestSet.class); + + public AdministrationTestSet() { + super(); + } + + @BeforeMethod(description = "startTest") + public void before() { + super.before(); + } + + @AfterMethod(description = "endTest") + public void afterAllIsSaidAndDone() { + super.afterAllIsSaidAndDone(); + } + + // **************** TESTS **************** + // ------ EMERGYA QA SAMPLE TEST ------ // + // ------ US00001 - Check google main page and do a search ------ // + /** + * Description: Check the main page elements and do a search on google + * + * Pre steps: + * - Open the browser + * + * Steps: + * - Go to localhost:8000/admin + * - Check that the Administracion Django is displayed + * - Check that the 'user' field is displayed + * - Write user + * - Check that the 'pass' field is displayed + * - Write pass + * - Check that the 'iniciar sesion' button is displayed + * - Click button + * - Check that the 'evento' button is displayed + * - Check that the 'añadir evento' button is displayed + * - Check that the 'modificar noticia' button is displayed + * - Click on news items + * - Check 'añadir news item' button is displayed + * - Click on this button + * - Check text title field is displayed + * - Check publish date is displayed + * - Check 'save' button is displayed + * - Write title + * - write description + * - click date + * - click time + * - borrar la noticia creada + * - volver al admin + * hecho + * darle a eventos + * comprobar campos + * crear evento + * borrar evento creado + * volver al admin + * Post steps: + * - Close the browser + * @throws InterruptedException + * + */ + @Test(description = "administrationMainPageSearch") + public void administrationMainPage() throws InterruptedException { + log.info("[log-TestSet]es que " + this.getClass().getName() + + "- Start administrationMainPage test"); + + // Variable declaration and definition + administrationMainPage = new AdministrationMainPage(driver); + + // Steps to build the stage (Pre steps) + + try { + // Go to localhost:8000/admin + // Check that the administracion django logo is displayed + isLogoDisplayed(); + + // Check that the user field is displayed + isFieldUserDisplayed(); + + // Check that the pass field is displayed + isFieldPassDisplayed(); + + // Check that the 'iniciar sesion' button is displayed + isSessionButtonDisplayed(); + + // Check if we can go to the web + administrationMainPage.doSearch(); + + Thread.sleep(5000); + + // Check that the 'evento' button is displayed + isEventButtonDisplayed(); + // Check that the 'añadir evento' button is displayed + isAddEventButtonDisplayed(); + // Check that the 'añadir noticia' button is displayed + isModifyNewsButtonDisplayed(); + // Click on news items + administrationMainPage = administrationMainPage + .clickOnNewsAdministrationPage(); + // Check 'añadir news item' button is displayed + isAddNewsButtonDisplayed(); + // Click on this button + administrationMainPage = administrationMainPage + .clickOnAddNewsAdministrationPage(); + + // Thread.sleep(5000); + + // Check text title field is displayed + isTitleNewsFieldDisplayed(); + // Check publish date is displayed + isDescriptionNewsDisplayed(); + // Check 'save' button is displayed + isSaveNewsButtonDisplayed(); + + // Thread.sleep(5000); + // Publish a new + administrationMainPage.addNew(); + + // Thread.sleep(5000); + + // Delete a new + administrationMainPage.deleteNew(); + // Thread.sleep(5000); + // go admin page + administrationMainPage.goAdmin(); + + // Click on events + administrationMainPage = administrationMainPage + .clickOnEventAdministrationPage(); + // Check 'añadir evento' button is displayed + isAddEventsButtonDisplayed(); + // Click on this button + administrationMainPage = administrationMainPage + .clickOnAddEventAdministrationPage(); + + // Thread.sleep(5000); + + // Check text title field is displayed + isTitleEventFieldDisplayed(); + // Check publish date is displayed + isDescriptionEventDisplayed(); + // Check 'save' button is displayed + isSaveEventButtonDisplayed(); + + // Thread.sleep(5000); + // Publish a new + administrationMainPage.addEvent(); + + // Thread.sleep(5000); + + // Delete a new + administrationMainPage.deleteEvent(); + // Thread.sleep(5000); + // go admin page + administrationMainPage.goAdmin(); + Thread.sleep(5000); + + } finally { + // Steps to clear the stage (Post steps) + } + + log.info("[log-TestSet] " + this.getClass().getName() + + "- End administrationMainPageSearch test"); + } + + // ************************ Methods ************************* + /** + * Checks if the search return several results + * @return true if there are several results and false in the opposite case + */ + public boolean checkSeveralResults() { + String resultClassName = "r"; + List elements = null; + boolean isSeveral = false; + + driver.wait(By.className(resultClassName), 20); + + if (driver.isElementDisplayed(By.className(resultClassName))) { + elements = driver.findElements(By.className(resultClassName)); + + if (elements.size() > 1) { + isSeveral = true; + } + } + + return isSeveral; + } + + // ************************ Assertions ************************* + /** + * This assertion check if the search return several results + */ + public void areSeveralResults() { + assertTrue( + "There aren't several results, it should have several results", + this.checkSeveralResults()); + } + + /** + * This assertion check if logo is displayed + */ + public void isLogoDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + assertTrue("The logo isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleByXPath("imgLogo")); + } + + /** + * This assertion check if user field is displayed + */ + public void isFieldUserDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + assertTrue("The user field isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleByXPath("userField")); + } + + /** + * This assertion check if pass field is displayed + */ + public void isFieldPassDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + assertTrue("The pass field isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleByXPath("passField")); + } + + /** + * This assertion check if session button is displayed + */ + public void isSessionButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The 'iniciar sesion' button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("sessionButton")); + } + + /** + * This assertion check if event button is displayed + */ + public void isEventButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue("The event button isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleByXPath("eventButton")); + } + + /** + * This assertion check if add event button is displayed + */ + public void isAddEventButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add event button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("addeventButton")); + } + + /** + * This assertion check if modify news button is displayed + */ + public void isModifyNewsButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The modify news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("modifynewsButton")); + }; + + /** + * this assertion check if add news item is displayed on the news item page + */ + public void isAddNewsButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("addnewsitemButton")); + }; + + public void isTitleNewsFieldDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleById("titlenewsfield")); + }; + + public void isDescriptionNewsDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleById("descriptionnews")); + }; + + public void isSaveNewsButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("savenewsbutton")); + }; + + /** + * this assertion check if add news item is displayed on the news item page + */ + public void isAddEventsButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("addeventsButton")); + }; + + public void isTitleEventFieldDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage.isElementVisibleById("titleeventfield")); + }; + + public void isDescriptionEventDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleById("descriptionevent")); + }; + + public void isSaveEventButtonDisplayed() { + if (administrationMainPage == null) { + administrationMainPage = new AdministrationMainPage(driver); + } + + /* Check by Name */ + assertTrue( + "The add news button isn't displayed, it should be displayed", + administrationMainPage + .isElementVisibleByXPath("saveeventbutton")); + }; + +} diff --git a/qa_selenium/src/test/java/com/emergya/testSets/GoogleTestSet.java b/qa_selenium/src/test/java/com/emergya/testSets/GoogleTestSet.java new file mode 100644 index 0000000..9080cb7 --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/testSets/GoogleTestSet.java @@ -0,0 +1,273 @@ +package com.emergya.testSets; + +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.emergya.pageObjects.EmergyaMainPage; +import com.emergya.pageObjects.GoogleMainPage; +import com.emergya.utils.DefaultTestSet; + +/** + * A test class contain the tests of a specific page in the application + * @author Jose Antonio Sanchez + * @author Ivan Bermudez + */ +public class GoogleTestSet extends DefaultTestSet { + + Logger log = Logger.getLogger(GoogleTestSet.class); + + public GoogleTestSet() { + super(); + } + + @BeforeMethod(description = "startTest") + public void before() { + super.before(); + } + + @AfterMethod(description = "endTest") + public void afterAllIsSaidAndDone() { + super.afterAllIsSaidAndDone(); + } + + // **************** TESTS **************** + // ------ EMERGYA QA SAMPLE TEST ------ // + // ------ US00001 - Check google main page and do a search ------ // + /** + * Description: Check the main page elements and do a search on google + * + * Pre steps: + * - Open the browser + * + * Steps: + * - Go to www.google.es + * - Check that the google logo is displayed + * - Check that the 'Buscar con Google' button is displayed + * - Check that the 'Voy a tener suerte' button is displayed + * - Check that the search field is displayed + * - Do this search 'Hello world!' + * - Check that several results are displayed + * + * Post steps: + * - Close the browser + * + */ + @Test(description = "googleMainPageSearch") + public void googleMainPageSearch() { + log.info("[log-TestSet]es que " + this.getClass().getName() + + "- Start googleMainPageSearch test"); + + // Variable declaration and definition + googleMainPage = new GoogleMainPage(driver); + + // Steps to build the stage (Pre steps) + + try { + // Go to www.google.es + // Check that the google logo is displayed + isLogoDisplayed(); + + // Check that the 'Buscar con Google' button is displayed + isSearchButtonDisplayed(); + + // Check that the 'Voy a tener suerte' button is displayed + isLuckButtonDisplayed(); + + // Check that the search field is displayed + isFieldSearchDisplayed(); + + // Do this search 'Hello world!' + googleMainPage.doSearch("Hello world"); + + // Check that several results are displayed + areSeveralResults(); + + } finally { + // Steps to clear the stage (Post steps) + } + + log.info("[log-TestSet] " + this.getClass().getName() + + "- End googleMainPageSearch test"); + } + + /** + * Description: Do a search in Google and access to a page + * + * Pre steps: + * - Open the browser + * + * Steps: + * - Go to www.google.es + * - Do this search 'www.emergya.es' + * - Access to 'www.emergya.es' + * - Check that the logo is displayed + * - Access to the 'Contacto' page + * - Check that the address is displayed + * - Access to the 'Trabaja con nosotros' page + * - Check '¿QUÉ OFRECEMOS?' section is displayed + * + * Post steps: + * - Close the browser + * + */ + @Test(description = "googleDoSearchAndAccessToPage") + public void googleDoSearchAndAccessToPage() { + log.info("[log-TestSet] " + this.getClass().getName() + + "- Start googleDoSearchAndAccessToPage test"); + + // Variable declaration and definition + googleMainPage = new GoogleMainPage(driver); + + // Steps to build the stage (Pre steps) + + try { + // Go to www.google.es + // Do this search 'www.emergya.es' + googleMainPage.doSearch("www.emergya.es"); + + // Access to 'www.emergya.es' + emergyaMainPage = googleMainPage.clickOnEmergyaPage(); + + // Check that the logo is displayed + isEmergyaLogoDisplayed(); + + // TODO: Remove the following line when you complete the test + // assertTrue("Developing test", false); + + // Access to the 'Contact' page + emergyaMainPage = emergyaMainPage.clickOnContactEmergyaPage(); + // Check that the address is displayed + isAddressEmergyaDisplayed(); + // Access to the 'Trabaja con nosotros' page + emergyaMainPage = emergyaMainPage.clickOnWorkEmergyaPage(); + // Check '¿QUÉ OFRECEMOS?' section is displayed + isOfferDisplayed(); + } finally { + // Steps to clear the stage (Post steps) + } + + log.info("[log-TestSet] " + this.getClass().getName() + + "- End googleDoSearchAndAccessToPage test"); + } + + // ************************ Methods ************************* + /** + * Checks if the search return several results + * @return true if there are several results and false in the opposite case + */ + public boolean checkSeveralResults() { + String resultClassName = "r"; + List elements = null; + boolean isSeveral = false; + + driver.wait(By.className(resultClassName), 20); + + if (driver.isElementDisplayed(By.className(resultClassName))) { + elements = driver.findElements(By.className(resultClassName)); + + if (elements.size() > 1) { + isSeveral = true; + } + } + + return isSeveral; + } + + // ************************ Assertions ************************* + /** + * This assertion check if the search return several results + */ + public void areSeveralResults() { + assertTrue( + "There aren't several results, it should have several results", + this.checkSeveralResults()); + } + + /** + * This assertion check if logo is displayed + */ + public void isLogoDisplayed() { + if (googleMainPage == null) { + googleMainPage = new GoogleMainPage(driver); + } + assertTrue("The logo isn't displayed, it should be displayed", + googleMainPage.isElementVisibleById("imgLogo")); + } + + /** + * This assertion check if search button is displayed + */ + public void isSearchButtonDisplayed() { + if (googleMainPage == null) { + googleMainPage = new GoogleMainPage(driver); + } + + /* Check by Name */ + assertTrue("The search button isn't displayed, it should be displayed", + googleMainPage.isElementVisibleByName("searchButton")); + } + + /** + * This assertion check if luck button is displayed + */ + public void isLuckButtonDisplayed() { + if (googleMainPage == null) { + googleMainPage = new GoogleMainPage(driver); + } + assertTrue("The luck button isn't displayed, it should be displayed", + googleMainPage.isElementVisibleByXPath("luckButton")); + } + + /** + * This assertion check if search field is displayed + */ + public void isFieldSearchDisplayed() { + if (googleMainPage == null) { + googleMainPage = new GoogleMainPage(driver); + } + assertTrue("The search field isn't displayed, it should be displayed", + googleMainPage.isElementVisibleByXPath("searchField")); + } + + /** + * This assertion check if emergya logo is displayed + */ + public void isEmergyaLogoDisplayed() { + if (emergyaMainPage == null) { + emergyaMainPage = new EmergyaMainPage(driver); + } + assertTrue("The logo isn't displayed, it should be displayed", + emergyaMainPage.isElementVisibleByXPath("imgLogoEmergya")); + } + + /** + * This assertion check if the address of Emergya Sevilla is displayed + */ + public void isAddressEmergyaDisplayed() { + if (emergyaMainPage == null) { + emergyaMainPage = new EmergyaMainPage(driver); + } + assertTrue("The address isn't displayed, it should be displayed", + emergyaMainPage.isElementVisibleByXPath("imgAddressEmergya")); + } + + /** + * This assertion check if the field of offer is displayed + */ + public void isOfferDisplayed() { + if (emergyaMainPage == null) { + emergyaMainPage = new EmergyaMainPage(driver); + } + assertTrue("The offer isn't displayed, it should be displayed", + emergyaMainPage.isElementVisibleByXPath("imgOfferEmergya")); + } + +} diff --git a/qa_selenium/src/test/java/com/emergya/utils/DefaultTestSet.java b/qa_selenium/src/test/java/com/emergya/utils/DefaultTestSet.java new file mode 100644 index 0000000..c356536 --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/utils/DefaultTestSet.java @@ -0,0 +1,336 @@ +package com.emergya.utils; + +import static org.monte.media.FormatKeys.EncodingKey; +import static org.monte.media.FormatKeys.FrameRateKey; +import static org.monte.media.FormatKeys.KeyFrameIntervalKey; +import static org.monte.media.FormatKeys.MIME_AVI; +import static org.monte.media.FormatKeys.MediaTypeKey; +import static org.monte.media.FormatKeys.MimeTypeKey; +import static org.monte.media.VideoFormatKeys.CompressorNameKey; +import static org.monte.media.VideoFormatKeys.DepthKey; +import static org.monte.media.VideoFormatKeys.ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE; +import static org.monte.media.VideoFormatKeys.QualityKey; +import static org.testng.AssertJUnit.assertTrue; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Method; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.apache.log4j.Logger; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; +import org.jdom.output.XMLOutputter; +import org.jdom.xpath.XPath; +import org.monte.media.Format; +import org.monte.media.FormatKeys.MediaType; +import org.monte.media.math.Rational; +import org.monte.screenrecorder.ScreenRecorder; +import org.monte.screenrecorder.ScreenRecorder.State; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; + +import com.emergya.drivers.EmergyaWebDriver; +import com.emergya.pageObjects.AdministrationMainPage; +import com.emergya.pageObjects.BasePageObject; +import com.emergya.pageObjects.EmergyaMainPage; +import com.emergya.pageObjects.GoogleMainPage; + +/** + * TestNG after and before methods + * @author Jose Antonio Sanchez + */ +public abstract class DefaultTestSet { + + protected static EmergyaWebDriver driver; + protected static Initialization config = Initialization.getInstance(); + protected AdministrationMainPage administrationMainPage; + protected GoogleMainPage googleMainPage; + protected EmergyaMainPage emergyaMainPage; + protected ScreenRecorder screenRecorder; + protected String tcName = ""; + private String failedSuitePath = "src/test/resources/suites/emergyaFailedTest.xml"; + + protected Logger log = Logger.getLogger(DefaultTestSet.class); + + @BeforeMethod + public void nameBefore(Method method) { + this.tcName = method.getName(); + } + + @BeforeMethod + public void before() { + driver = config.initialize(); + + if (driver != null && config.isRecordVideo() == true) { + long startTime = System.currentTimeMillis(); + try { + log.info("Recording video"); + + GraphicsConfiguration gc = GraphicsEnvironment + .getLocalGraphicsEnvironment().getDefaultScreenDevice() + .getDefaultConfiguration(); + + this.screenRecorder = new ScreenRecorder(gc, null, + new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, + MIME_AVI), + new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, + ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, + CompressorNameKey, + ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, DepthKey, + 24, FrameRateKey, Rational.valueOf(15), + QualityKey, 1.0f, KeyFrameIntervalKey, 15 * 60), + new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, + "black", FrameRateKey, Rational.valueOf(30)), + null, new File(config.getVideoRecordingPath())); + + screenRecorder.start(); + } catch (Exception e) { + log.warn( + "Recorder could not be initilized. No video will be recording"); + } + log.info("Start recording in " + + (System.currentTimeMillis() - startTime) + " ms"); + } else { + log.info("No video recording"); + } + } + + @AfterMethod + public void afterAllIsSaidAndDone() { + log.info("Function afterAllIsSaidAndDone"); + + if (driver != null) { + if (driver != null) { + driver.manage().deleteAllCookies(); + driver.quit(); + } + } + } + + @AfterMethod + public void recordVideo(ITestResult result) { + if (driver != null && (config.isRecordVideo() == true) + && (screenRecorder != null) + && (screenRecorder.getState().equals(State.RECORDING))) { + + long startTime = System.currentTimeMillis(); + + try { + screenRecorder.stop(); + log.info("Recorder stoped"); + File tempRecordeFile = screenRecorder.getCreatedMovieFiles() + .get(0); + + if ((!config.isSaveVideoForPassed()) + && (result.getStatus() == 1)) { + log.info("Test passed. Deleting video"); + + if (tempRecordeFile.delete()) { + log.info("File deleted"); + } else { + log.warn("Video could not be deleted"); + } + } else { + String endPath = tempRecordeFile.getAbsolutePath() + .replaceAll("ScreenRecording", this.tcName); + if (tempRecordeFile.renameTo(new File(endPath))) { + log.info("File stored in " + endPath); + } else { + log.warn("Video could not be stored in " + endPath); + } + } + } catch (IOException e) { + log.warn("Recorder could not be stoped"); + } + + log.info("Recording video took " + + (System.currentTimeMillis() - startTime) + " ms"); + } + } + + @AfterMethod + public void checkFailedTest(ITestResult result) { + if (result.getMethod().getXmlTest().getName().equals("FailedTests")) { + removePassedTestToXML(result.getMethod().getRealClass().getName(), + result.getMethod().getMethodName()); + } else { + log.info("checkFailedTest.........result status of test is: " + + result.getStatus()); + + if (result.getStatus() == 2) { + log.info("name Of the xml TestSuite is " + + result.getMethod().getXmlTest().getName()); + + if (!result.getMethod().getXmlTest().getName() + .equals("Default test")) { + addFailedTestToXML( + result.getMethod().getRealClass().getName(), + result.getMethod().getMethodName()); + } + } else { + if (!result.getMethod().getXmlTest().getName() + .equals("Default test")) { + removePassedTestToXML( + result.getMethod().getRealClass().getName(), + result.getMethod().getMethodName()); + } + } + } + } + + // *** Public methods ***// + /** + * Obtains the initialization configuration + * @return initialization instance + */ + public static Initialization getConfig() { + return config; + } + + /** + * Method to get a timestamp + * @return string with the timestamp + */ + public static String getTimeStamp() { + String timeStamp = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss") + .format(Calendar.getInstance().getTime()); + return timeStamp; + } + + // *** Private methods ***// + /** + * Method to add failed test to a xml file + * @param suite name + * @param testName name of the test + */ + private void addFailedTestToXML(String suite, String testName) { + try { + SAXBuilder builder = new SAXBuilder(); + Document doc = builder.build(new FileInputStream(failedSuitePath)); + + Element foundElement = (Element) XPath.selectSingleNode(doc, + "/suite/test/classes/class[@name='" + suite + + "']/methods/include[@name='" + testName + "']"); + + if (foundElement == null) { + Element foundClass = (Element) XPath.selectSingleNode(doc, + "/suite/test/classes/class[@name='" + suite + "']"); + + if (foundClass != null) { + // Adding the method element + Element methodsElement = foundClass.getChild("methods"); + + // Adding the include element with the test name + Element includeElement = new Element("include"); + includeElement.setAttribute("name", testName); + methodsElement.addContent(includeElement); + + XMLOutputter xmlOutput = new XMLOutputter(); + xmlOutput.setFormat( + org.jdom.output.Format.getPrettyFormat()); + xmlOutput.output(doc, new FileWriter(failedSuitePath)); + } else { + Element rootElement = doc.getRootElement(); + + Element testElement = rootElement.getChild("test"); + + Element classesElement = testElement.getChild("classes"); + + // Adding the class element with the testSet name + Element classElement = new Element("class"); + classElement.setAttribute("name", suite); + classesElement.addContent(classElement); + + // Adding the method element + Element methodsElement = new Element("methods"); + classElement.addContent(methodsElement); + + // Adding the include element with the test name + Element includeElement = new Element("include"); + includeElement.setAttribute("name", testName); + methodsElement.addContent(includeElement); + + XMLOutputter xmlOutput = new XMLOutputter(); + xmlOutput.setFormat( + org.jdom.output.Format.getPrettyFormat()); + xmlOutput.output(doc, new FileWriter(failedSuitePath)); + } + } else { + log.info( + "The test is already added in the xml of failed tests"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Method to remove passed test of the xml file + * @param suite name + * @param testName name of the test + */ + private void removePassedTestToXML(String suite, String testName) { + try { + SAXBuilder builder = new SAXBuilder(); + Document doc = builder.build(new FileInputStream(failedSuitePath)); + + Element rootElement = doc.getRootElement(); + Element testElement = rootElement.getChild("test"); + Element classesElement = testElement.getChild("classes"); + Element test = (Element) XPath.selectSingleNode(doc, + "/suite/test/classes/class[@name='" + suite + + "']/methods/include[@name='" + testName + "']"); + if (test != null) { + if (XPath.selectNodes(doc, "/suite/test/classes/class[@name='" + + suite + "']/methods/include").size() > 1) { + + Element testToRemove = (Element) XPath.selectSingleNode(doc, + "/suite/test/classes/class[@name='" + suite + + "']/methods/include[@name='" + testName + + "']"); + Element methodElement = (Element) XPath.selectSingleNode( + doc, "/suite/test/classes/class[@name='" + suite + + "']/methods"); + + methodElement.removeContent(testToRemove); + XMLOutputter xmlOutput = new XMLOutputter(); + xmlOutput.setFormat( + org.jdom.output.Format.getPrettyFormat()); + xmlOutput.output(doc, new FileWriter(failedSuitePath)); + } else { + classesElement.removeContent( + test.getParentElement().getParentElement()); + XMLOutputter xmlOutput = new XMLOutputter(); + xmlOutput.setFormat( + org.jdom.output.Format.getPrettyFormat()); + xmlOutput.output(doc, new FileWriter(failedSuitePath)); + } + + } else { + log.info("The test not exists in the xml of failed tests"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Checks that the PO is ready + * @param pageObject page object to be used + */ + protected void isReady(BasePageObject pageObject) { + assertTrue( + "The PO " + pageObject.getClass().getName() + " is not ready", + pageObject.isReady()); + } +} diff --git a/qa_selenium/src/test/java/com/emergya/utils/Factory.java b/qa_selenium/src/test/java/com/emergya/utils/Factory.java new file mode 100644 index 0000000..e305591 --- /dev/null +++ b/qa_selenium/src/test/java/com/emergya/utils/Factory.java @@ -0,0 +1,9 @@ +package com.emergya.utils; + +/** + * Generic class to do pre-steps and post-steps method + * @author Jose Antonio Sanchez + */ +public class Factory extends DefaultTestSet { + // Generic class to do pre-steps and post-steps method +} diff --git a/qa_selenium/src/test/resources/files/software/IEDriverServer.exe b/qa_selenium/src/test/resources/files/software/IEDriverServer.exe new file mode 100644 index 0000000..6efc9c7 Binary files /dev/null and b/qa_selenium/src/test/resources/files/software/IEDriverServer.exe differ diff --git a/qa_selenium/src/test/resources/files/software/chromedriver b/qa_selenium/src/test/resources/files/software/chromedriver new file mode 100644 index 0000000..ccb5872 Binary files /dev/null and b/qa_selenium/src/test/resources/files/software/chromedriver differ diff --git a/qa_selenium/src/test/resources/files/software/chromedriver.exe b/qa_selenium/src/test/resources/files/software/chromedriver.exe new file mode 100644 index 0000000..1f8a63b Binary files /dev/null and b/qa_selenium/src/test/resources/files/software/chromedriver.exe differ diff --git a/qa_selenium/src/test/resources/log4j.properties b/qa_selenium/src/test/resources/log4j.properties new file mode 100644 index 0000000..50ca4de --- /dev/null +++ b/qa_selenium/src/test/resources/log4j.properties @@ -0,0 +1,10 @@ +# This file sets the logging properties, in this case the output to console + +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/qa_selenium/src/test/resources/selectors/administrationmainpage.properties b/qa_selenium/src/test/resources/selectors/administrationmainpage.properties new file mode 100644 index 0000000..f2014b8 --- /dev/null +++ b/qa_selenium/src/test/resources/selectors/administrationmainpage.properties @@ -0,0 +1,102 @@ +#Logo +imgLogo.xpath=.//*[@id='header'] +#imgAddressEmergya.xpath=//*[@id='block-views-sedes-block']/div/div/div/ul/li[1]/span/div/div +#imgOfferEmergya.xpath=//*[@id='block-block-8']/div/div/div[2] + +#User field +userField.id=id_username +userField.xpath=.//*[@id='id_username'] + +#Pass field +passField.id=id_password +passField.xpath=.//*[@id='id_password'] + +#Session Button +sessionButton.xpath=.//*[@id='login-form']/div[3]/input + +#Event Button +eventButton.xpath=.//*[@id='content-main']/div[2]/table/tbody/tr[1]/th/a + +#Add Event Button +addeventButton.xpath=.//*[@id='content-main']/div[2]/table/tbody/tr[1]/td[1]/a + +#Modify News Button +modifynewsButton.xpath=.//*[@id='content-main']/div[2]/table/tbody/tr[2]/td[2]/a + +#News item Button +newsitemButton.xpath=.//*[@id='content-main']/div[2]/table/tbody/tr[2]/th/a + +#Add news item button +addnewsitemButton.xpath=.//*[@id='content-main']/ul/li/a + +#title news field +titlenewsfield.id=id_title +#description news field +descriptionnews.id=id_description +#save news button +savenewsbutton.xpath=.//*[@id='newsitem_form']/div/div/input[1] + +#date news click +datenews.xpath=.//*[@id='newsitem_form']/div/fieldset/div[3]/div/p/span[1]/a[1] +#time news click +timenews.xpath=.//*[@id='newsitem_form']/div/fieldset/div[3]/div/p/span[2]/a[1] + +#select a news +selectnews.xpath=.//*[@id='result_list']/tbody/tr[1]/td/input +#select delete news +selectdelete.xpath=.//*[@id='changelist-form']/div[1]/label/select/option[2] +#delete news +deletenews.xpath=.//*[@id='changelist-form']/div[1]/button +#confirm delete news +confirmdelete.xpath=.//*[@id='content']/form/div/input[4] + + + + +# events + +#Add event button +addeventsButton.xpath=.//*[@id='content-main']/ul/li/a + +#title event field +titleeventfield.id=id_title +#description news field +descriptionevent.id=id_description +#save news button +saveeventbutton.xpath=.//*[@id='event_form']/div/div/input[1] + +#dateeventstartclick +dateeventstart.xpath=.//*[@id='event_form']/div/fieldset/div[3]/div/p/span[1]/a[1] +#timeeventstartclick +timeeventstart.xpath=.//*[@id='event_form']/div/fieldset/div[3]/div/p/span[2]/a[1] +#dateeventendclick +dateeventend.xpath=.//*[@id='event_form']/div/fieldset/div[4]/div/p/span[1]/a[1] +#timeeventendclick +timeeventend.xpath=.//*[@id='event_form']/div/fieldset/div[4]/div/p/span[2]/a[1] +#select an event +selectevent.xpath=.//*[@id='result_list']/tbody/tr[1]/td/input +#select delete event +selectdeleteevent.xpath=.//*[@id='changelist-form']/div[1]/label/select/option[2] +#delete event +deleteevent.xpath=.//*[@id='changelist-form']/div[1]/button +#confirm delete event +confirmdeleteevent.xpath=.//*[@id='content']/form/div/input[4] + + + + + + + + + + + + + + + + + + + diff --git a/qa_selenium/src/test/resources/selectors/emergyamainpage.properties b/qa_selenium/src/test/resources/selectors/emergyamainpage.properties new file mode 100644 index 0000000..d116606 --- /dev/null +++ b/qa_selenium/src/test/resources/selectors/emergyamainpage.properties @@ -0,0 +1,4 @@ +#Logo +imgLogoEmergya.xpath=//img[@class='site-logo image-style-none'] +imgAddressEmergya.xpath=//*[@id='block-views-sedes-block']/div/div/div/ul/li[1]/span/div/div +imgOfferEmergya.xpath=//*[@id='block-block-8']/div/div/div[2] \ No newline at end of file diff --git a/qa_selenium/src/test/resources/selectors/googlemainpage.properties b/qa_selenium/src/test/resources/selectors/googlemainpage.properties new file mode 100644 index 0000000..6b9698b --- /dev/null +++ b/qa_selenium/src/test/resources/selectors/googlemainpage.properties @@ -0,0 +1,15 @@ +#Search field +searchField.id=lst-ib +searchField.xpath=//input[@id='lst-ib'] + +#Logo +imgLogo.id=hplogo +imgLogo.xpath=//div[@id='hplogo'] + +#Voy a tener suerte button +luckButton.xpath=//input[@aria-label='Voy a tener suerte'] + +#Buscar con Google button +searchButton.xpath=//input[@aria-label='Buscar con Google'] +searchButton.name=btnK +smallSearchButton.id=sblsbb \ No newline at end of file diff --git a/qa_selenium/src/test/resources/suites/R1.0/R1.0-S1/US00001.xml b/qa_selenium/src/test/resources/suites/R1.0/R1.0-S1/US00001.xml new file mode 100644 index 0000000..3bc8981 --- /dev/null +++ b/qa_selenium/src/test/resources/suites/R1.0/R1.0-S1/US00001.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/qa_selenium/src/test/resources/suites/emergyaAcceptanceTest.xml b/qa_selenium/src/test/resources/suites/emergyaAcceptanceTest.xml new file mode 100644 index 0000000..3df9e7d --- /dev/null +++ b/qa_selenium/src/test/resources/suites/emergyaAcceptanceTest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/qa_selenium/src/test/resources/suites/emergyaFailedTest.xml b/qa_selenium/src/test/resources/suites/emergyaFailedTest.xml new file mode 100644 index 0000000..5bcb73f --- /dev/null +++ b/qa_selenium/src/test/resources/suites/emergyaFailedTest.xml @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/qa_selenium/src/test/resources/suites/emergyaRegressionTest.xml b/qa_selenium/src/test/resources/suites/emergyaRegressionTest.xml new file mode 100644 index 0000000..eb11af0 --- /dev/null +++ b/qa_selenium/src/test/resources/suites/emergyaRegressionTest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/qa_selenium/src/test/resources/test.properties b/qa_selenium/src/test/resources/test.properties new file mode 100644 index 0000000..f14a733 --- /dev/null +++ b/qa_selenium/src/test/resources/test.properties @@ -0,0 +1,25 @@ +# This file contain properties, some are defined here and others are read from the pom.xml + +# Browser +browser=${browser} + +# Entorno +environment=${environment.url} + +# Context +context=${env.context} + +# OS +OS=${local.OS} + +# FilesPath +screenshotPath=files/screenshots +downloadPath=files/downloads + +# Video recording +videoRecordingPath=${video.Recording.Path} +activateVideoRecording=${activate.Video.Recording} +saveVideoForPassed=${save.Video.For.Passed} + +# IDE enabled +ideEnabled=${ide.Enabled} \ No newline at end of file