Added excel file upon completion

This commit is contained in:
2020-08-15 19:50:38 +01:00
parent 8e96ec6720
commit 6e12fe07c5
9 changed files with 344 additions and 165 deletions

58
.idea/artifacts/JobApplications_jar.xml generated Normal file
View File

@@ -0,0 +1,58 @@
<component name="ArtifactManager">
<artifact type="jar" name="JobApplications:jar">
<output-path>$PROJECT_DIR$/out/artifacts/JobApplications_jar</output-path>
<root id="archive" name="JobApplications.jar">
<element id="module-output" name="JobApplications" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml/4.1.1/poi-ooxml-4.1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/github/microutils/kotlin-logging/1.6.22/kotlin-logging-1.6.22.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/github/microutils/kotlin-logging-common/1.6.22/kotlin-logging-common-1.6.22.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-compress/1.19/commons-compress-1.19.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-ie-driver/3.141.59/selenium-ie-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-java/3.141.59/selenium-java-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/tylerthrailkill/helpers/pretty-print/2.0.2/pretty-print-2.0.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/ch/qos/logback/logback-core/1.3.0-alpha4/logback-core-1.3.0-alpha4.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-firefox-driver/3.141.59/selenium-firefox-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.3.61/kotlin-stdlib-1.3.61.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-remote-driver/3.141.59/selenium-remote-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/sun/mail/javax.mail/1.6.0/javax.mail-1.6.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.13/commons-codec-1.13.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/guava/guava/25.0-jre/guava-25.0-jre.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/poi/poi-ooxml-schemas/4.1.1/poi-ooxml-schemas-4.1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/ch/qos/logback/logback-classic/1.3.0-alpha4/logback-classic-1.3.0-alpha4.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.61/kotlin-stdlib-jdk7-1.3.61.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/xmlbeans/xmlbeans/3.1.0/xmlbeans-3.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-opera-driver/3.141.59/selenium-opera-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/squareup/retrofit2/retrofit/2.6.0/retrofit-2.6.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-api/3.141.59/selenium-api-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/ibm/icu/icu4j/63.1/icu4j-63.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/squareup/retrofit2/converter-gson/2.6.0/converter-gson-2.6.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.0.0/checker-compat-qual-2.0.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/squareup/okio/okio/1.14.0/okio-1.14.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/bytebuddy/byte-buddy/1.8.15/byte-buddy-1.8.15.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-edge-driver/3.141.59/selenium-edge-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/json/json/20190722/json-20190722.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.3.61/kotlin-stdlib-jdk8-1.3.61.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/virtuald/curvesapi/1.06/curvesapi-1.06.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-support/3.141.59/selenium-support-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.3.3/kotlinx-coroutines-core-1.3.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/poi/poi/4.1.1/poi-4.1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-safari-driver/3.141.59/selenium-safari-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/squareup/okhttp3/okhttp/3.11.0/okhttp-3.11.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.1.3/error_prone_annotations-2.1.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-simple/1.6.1/slf4j-simple-1.6.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/seleniumhq/selenium/selenium-chrome-driver/3.141.59/selenium-chrome-driver-3.141.59.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.61/kotlin-stdlib-common-1.3.61.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.8.0-beta1/slf4j-api-1.8.0-beta1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.3.11/kotlin-reflect-1.3.11.jar" path-in-jar="/" />
</root>
</artifact>
</component>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -75,6 +75,12 @@
<artifactId>kotlinx-coroutines-core</artifactId> <artifactId>kotlinx-coroutines-core</artifactId>
<version>1.3.3</version> <version>1.3.3</version>
</dependency> </dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>1.3.61</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
@@ -119,6 +125,8 @@
<configuration> <configuration>
<archive> <archive>
<manifest> <manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>Main</mainClass> <mainClass>Main</mainClass>
</manifest> </manifest>
</archive> </archive>

View File

@@ -1,3 +1,5 @@
import api.network.responses.ReedJobObject
import java.time.LocalDateTime
import java.util.* import java.util.*
data class JobObject( data class JobObject(
@@ -10,7 +12,12 @@ data class JobObject(
var dateApplied : String? = null var dateApplied : String? = null
){ ){
override fun toString(): String { constructor(job: ReedJobObject): this(
return super.toString() jobId = job.jobId.toString(),
} website = job.jobUrl,
jobTitle = job.jobTitle,
location = job.locationName,
company = job.employerName,
dateApplied = LocalDateTime.now().toString()
)
} }

View File

@@ -11,111 +11,111 @@ import kotlin.math.roundToInt
fun StartSearch(){ fun StartSearch(){
//Open Chrome // //Open Chrome
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe" ) // System.setProperty("webdriver.chrome.driver","C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe" )
val driver = ChromeDriver() // val driver = ChromeDriver()
//
//open reed website login // //open reed website login
driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin") // driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin")
val wait = WebDriverWait(driver, 20) // val wait = WebDriverWait(driver, 20)
//
//wait for page to load // //wait for page to load
val lastElementToLoad = driver.findElementById("signin-button") // val lastElementToLoad = driver.findElementById("signin-button")
wait.until(ExpectedConditions.elementToBeClickable(lastElementToLoad)) // wait.until(ExpectedConditions.elementToBeClickable(lastElementToLoad))
//
//insert credentials and sign in // //insert credentials and sign in
driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME) // driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME)
driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD) // driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD)
lastElementToLoad.click() // lastElementToLoad.click()
//
//wait for page to load // //wait for page to load
val jobSearchEditText = driver.findElementByXPath("//*[@id=\"keywords\"]") // val jobSearchEditText = driver.findElementByXPath("//*[@id=\"keywords\"]")
wait.until(ExpectedConditions.elementToBeClickable(jobSearchEditText)) // wait.until(ExpectedConditions.elementToBeClickable(jobSearchEditText))
//
// //submit search //// //submit search
jobSearchEditText.sendKeys(REED_KEYWORDS) // jobSearchEditText.sendKeys(REED_KEYWORDS)
driver.findElementByXPath("//*[@id=\"location\"]").sendKeys(REED_LOCATION) // driver.findElementByXPath("//*[@id=\"location\"]").sendKeys(REED_LOCATION)
driver.findElementByXPath("//*[@id=\"main-search\"]/div[1]/div[3]/button").click() // driver.findElementByXPath("//*[@id=\"main-search\"]/div[1]/div[3]/button").click()
//
//todo: change to wait // //todo: change to wait
Thread.sleep(1500) // Thread.sleep(1500)
//
val ad = driver.findElementByXPath("//*[@id=\"content\"]/div[1]/div[2]/h1") // val ad = driver.findElementByXPath("//*[@id=\"content\"]/div[1]/div[2]/h1")
wait.until(ExpectedConditions.elementToBeClickable(ad)) // wait.until(ExpectedConditions.elementToBeClickable(ad))
//
//find number of pages // //find number of pages
val text = driver.findElementByCssSelector("div.page-counter").text /* eg. 1 - 25 of 99 jobs */ // val text = driver.findElementByCssSelector("div.page-counter").text /* eg. 1 - 25 of 99 jobs */
print(text) // print(text)
val count = text.toTotalCount() // val count = text.toTotalCount()
val pages = count.getNumberOfPages() // val pages = count.getNumberOfPages()
//
//loop through pages of search // //loop through pages of search
for (i in 1..pages){ // for (i in 1..pages){
//
//open page by number on search // //open page by number on search
//todo: change this url builder // //todo: change this url builder
driver.get("https://www.reed.co.uk/jobs/android-developer-jobs-in-kilburn-london?pageno=$i") // driver.get("https://www.reed.co.uk/jobs/android-developer-jobs-in-kilburn-london?pageno=$i")
Thread.sleep(2500) // Thread.sleep(2500)
//
//elements list of jobs on page // //elements list of jobs on page
val list = driver.findElementsByCssSelector("div.col-sm-12.col-md-9.col-lg-10.details") // val list = driver.findElementsByCssSelector("div.col-sm-12.col-md-9.col-lg-10.details")
//
//turn list into global list job object // //turn list into global list job object
list.forEach { // list.forEach {
val badge = it.findElement(By.cssSelector("div.badge-container")) // val badge = it.findElement(By.cssSelector("div.badge-container"))
//check if there is a badge element // //check if there is a badge element
if (badge.isDisplayed){ // if (badge.isDisplayed){
//see if applied is in badge // //see if applied is in badge
val applied = badge.findElements(By.cssSelector("span.label.label-applied")) // val applied = badge.findElements(By.cssSelector("span.label.label-applied"))
//if applied doesnt exist then add to global list of jobs // //if applied doesnt exist then add to global list of jobs
if (applied.isNullOrEmpty()){ // if (applied.isNullOrEmpty()){
val jobObject = it.toJobObject() // val jobObject = it.toJobObject()
jobsList.add(jobObject) // jobsList.add(jobObject)
} // }
//
}else{ // }else{
//no badge exists so add to list of jobs declared at the top // //no badge exists so add to list of jobs declared at the top
val jobObject = it.toJobObject() // val jobObject = it.toJobObject()
jobsList.add(jobObject) // jobsList.add(jobObject)
} // }
} // }
} // }
//
//loop through the jobs collected // //loop through the jobs collected
jobsList.forEach{ // jobsList.forEach{
//open the URl // //open the URl
driver.get(it.url) // driver.get(it.url)
//
val title = driver.findElementByXPath("//*[@id=\"content\"]/div/div[2]/article") // val title = driver.findElementByXPath("//*[@id=\"content\"]/div/div[2]/article")
wait.until(ExpectedConditions.elementToBeClickable(title)) // wait.until(ExpectedConditions.elementToBeClickable(title))
//
//check for external apply element // //check for external apply element
val applyExternal = driver.findElementsByCssSelector("span.external-app-caption") // val applyExternal = driver.findElementsByCssSelector("span.external-app-caption")
//
//if external apply is empty then apply for job // //if external apply is empty then apply for job
if (applyExternal.isNullOrEmpty()){ // if (applyExternal.isNullOrEmpty()){
//
print(it.jobTitle + " ${it.url} \n" ) // print(it.jobTitle + " ${it.url} \n" )
//
//
//find apply button // //find apply button
val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]") // val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]")
//
if (!applyNow.isNullOrEmpty()){ // if (!applyNow.isNullOrEmpty()){
//
//click apply // //click apply
applyNow[1].click() // applyNow[1].click()
//
try{ // try{
val successfulApplied = driver.findElementByXPath("//*[@id=\"content\"]/div/div[1]/a") // val successfulApplied = driver.findElementByXPath("//*[@id=\"content\"]/div/div[1]/a")
wait.until(ExpectedConditions.visibilityOf(successfulApplied)) // wait.until(ExpectedConditions.visibilityOf(successfulApplied))
}catch (e: Exception){ // }catch (e: Exception){
println(it.jobId + " did not apply") // println(it.jobId + " did not apply")
println("\n" + e.toString() + "\n") // println("\n" + e.toString() + "\n")
} // }
} // }
} // }
} // }
} }

View File

@@ -0,0 +1,80 @@
import api.network.responses.ReedJobObject
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.awt.Desktop
import java.io.File
import java.io.FileOutputStream
import java.time.LocalDate
import kotlin.reflect.full.memberProperties
fun List<ReedJobObject>.writeToOut(){
try {
val workbook = XSSFWorkbook()
val sheet = workbook.createSheet("sheet1") // creating a blank sheet
val headerList = takeKClass<ReedJobObject>()
val topRow = sheet.createRow(0)
ReedJobObject::class.memberProperties.forEachIndexed { headerPos, item ->
topRow.createCell(headerPos).setCellValue(headerList[headerPos])
}
this.forEachIndexed { index, reedJobObject ->
val row = sheet.createRow(index + 1)
ReedJobObject::class.memberProperties.forEachIndexed { headerPos, item ->
row.createCell(headerPos).setCellValue(item.get(reedJobObject).toString())
}
}
val dateTime = LocalDate.now().toString()
val file = File("E:\\Reed search output\\Jobs applied - ${dateTime}.xlsx")
val out = FileOutputStream(file) // file name with path
workbook.write(out)
out.close()
val desktop = Desktop.getDesktop()
if (file.exists()) //checks file exists or not
desktop.open(file) //opens the specified file
} catch (e: Exception) {
e.printStackTrace()
}
}
//inline fun <reified T : Any> List<T>.writeToExcel() {
// try {
// val workbook = XSSFWorkbook()
// val sheet = workbook.createSheet("sheet1") // creating a blank sheet
// var rownum = 0
//
// val headerList = takeKClass<T>()
//
//
// for (user in this) {
//
// val row: Row = sheet.createRow(rownum++)
// createList(user, row)
// }
// val out = FileOutputStream(File("NewFile.xlsx")) // file name with path
// workbook.write(out)
// out.close()
// } catch (e: Exception) {
// e.printStackTrace()
// }
//}
inline fun <reified T: Any> takeKClass(): List<String> {
val reflection = T::class
return reflection.members.map { it.name }
}
inline fun <reified T: Any> List<T>.getElements(): List<List<String>> {
val reflection = T::class
return this.map {
reflection.memberProperties.map { kProperty1 ->
kProperty1.get(it).toString()
}
}
}

View File

@@ -4,72 +4,78 @@ import api.network.NetworkRequests
import api.network.responses.ReedJobObject import api.network.responses.ReedJobObject
import org.openqa.selenium.JavascriptExecutor import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.chrome.ChromeDriver import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.support.ui.ExpectedConditions
import org.openqa.selenium.support.ui.WebDriverWait import org.openqa.selenium.support.ui.WebDriverWait
import kotlin.system.exitProcess
var jobsList = mutableListOf<JobObject>() var appliedJobsList = mutableListOf<ReedJobObject>()
var reedJobsList = listOf<ReedJobObject>() var reedJobsList = listOf<ReedJobObject>()
lateinit var driver: ChromeDriver lateinit var driver: ChromeDriver
lateinit var wait: WebDriverWait lateinit var wait: WebDriverWait
const val driverPath = "C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe"
public fun main(args: Array<String>){ public fun main(args: Array<String>){
setup() getJobsFromReedApi()
setupWebDriver() setupWebDriver()
logonToReed() logonToReed()
applyForJobsThroughLoop() applyForJobsThroughLoop {
appliedJobsList.writeToOut()
driver.close()
exitProcess(2)
}
} }
fun setup(){ fun getJobsFromReedApi(){
val result = NetworkRequests().getSearchApi() val result = NetworkRequests().getSearchApi()
result?.let {
if (!result.isNullOrEmpty()){ reedJobsList = it
reedJobsList = result return
} }
// No results found so exit
exitProcess(2)
} }
fun setupWebDriver(){ fun setupWebDriver(){
//Open Chrome //Open Chrome
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe" ) System.setProperty("webdriver.chrome.driver", driverPath)
driver = ChromeDriver() driver = ChromeDriver()
wait = WebDriverWait(driver, 20) wait = WebDriverWait(driver, 20)
} }
fun applyForJobsThroughLoop(){
reedJobsList.forEach {
try {
driver.get(it.jobUrl)
applyForJob(it)
}catch (e: Exception){
println("\n" + e.toString() + "\n")
}
}
}
fun logonToReed(){ fun logonToReed(){
driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin") driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin")
waitForPageToLoad()
//wait for page to load
val lastElementToLoad = driver.findElementById("signin-button")
wait.until(ExpectedConditions.elementToBeClickable(lastElementToLoad))
//insert credentials and sign in //insert credentials and sign in
driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME) driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME)
driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD) driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD)
lastElementToLoad.click()
//wait for page to load // Click login and wait for page to load
val jobSearchEditText = driver.findElementByXPath("//*[@id=\"keywords\"]") driver.findElementById("signin-button").click()
wait.until(ExpectedConditions.elementToBeClickable(jobSearchEditText)) waitForPageToLoad()
}
fun applyForJobsThroughLoop(
complete: () -> Unit
){
reedJobsList.forEach {
try {
// load url
driver.get(it.jobUrl)
// load [age
waitForPageToLoad()
// apply for job
applyForJob(it)
}catch (e: Exception){
e.printStackTrace()
}
}
complete()
} }
fun applyForJob(jobObject: ReedJobObject){ fun applyForJob(jobObject: ReedJobObject){
val appliedBefore = driver.findElementsByXPath("//*[@id=\"content\"]/div/div[2]/article/div/div[1]/div")
if (appliedBefore.isNullOrEmpty()){ if (hasUserNotAppliedBefore()){
println("${jobObject.jobId} has not been applied") println("${jobObject.jobId} has not been applied")
//find apply button //find apply button
val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]") val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]")
@@ -78,22 +84,27 @@ fun applyForJob(jobObject: ReedJobObject){
//click apply //click apply
val index = if (applyNow.size > 1){ 1 }else{ 0 } val index = if (applyNow.size > 1){ 1 }else{ 0 }
applyNow[index].click() applyNow[index].click()
waitForPageToLoad()
try{ println("${jobObject.jobId} has now been applied for")
// val successfulApplied = driver.findElementByCssSelector("div.alert.alert-success alert-borderless") appliedJobsList.add(jobObject)
wait.until{ return
driver.executeScript("return document.readyState") == "complete"
}
}catch (e: Exception){
println("\n" + e.toString() + "\n")
}
} }
println("${jobObject.jobId} could not be applied for")
}else{ }else{
println("${jobObject.jobId} has been applied") println("${jobObject.jobId} has been applied for previously")
} }
} }
// Checks to see if user has applied before
fun hasUserNotAppliedBefore(): Boolean{
// find "applied before" text
val appliedBefore = driver.findElementsByXPath("//*[@id=\"content\"]/div/div[2]/article/div/div[1]/div")
return appliedBefore.isNullOrEmpty()
}
fun waitForPageToLoad(){
//wait for page to load
wait.until{driv ->
(driv as JavascriptExecutor).executeScript("return document.readyState") == "complete"
}
}

View File

@@ -1,30 +1,29 @@
package api.network package api.network
import Constants.Companion.REED_KEYWORDS import Constants.Companion.REED_KEYWORDS
import Constants.Companion.REED_LOCATION
import Constants.Companion.REED_MINIMUM_SALARY import Constants.Companion.REED_MINIMUM_SALARY
import api.network.responses.ReedJobObject import api.network.responses.ReedJobObject
import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.ReedApi import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.ReedApi
import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.SafeApiRequest import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.SafeApiRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
class NetworkRequests : SafeApiRequest(){ class NetworkRequests : SafeApiRequest(){
val reedApi = ReedApi() val reedApi by lazy { ReedApi() }
fun getSearchApi() : List<ReedJobObject>?{ fun getSearchApi() : List<ReedJobObject>?{
try { try {
val response = runBlocking { apiRequest { reedApi.getGameData(REED_KEYWORDS, REED_LOCATION, REED_MINIMUM_SALARY) } } // get results from Api
val response = runBlocking {
apiRequest { reedApi.getReedData(REED_KEYWORDS, REED_MINIMUM_SALARY) }
}
// check we have results
response.results?.let { response.results?.let {
return it return it
} }
}catch (e : Exception){ }catch (e : Exception){
println("*** $e") e.printStackTrace()
} }
return null return null
} }

View File

@@ -14,12 +14,22 @@ import retrofit2.http.Query
interface ReedApi { interface ReedApi {
//get the game data from api call of relevent gameID //get the job data from api call to Reed api data service
@GET("search") @GET("search")
suspend fun getGameData(@Query("keywords") keywords: String, suspend fun getReedData(@Query("keywords") keywords: String,
@Query("minimumSalary") minimumSalary: String) : Response<ReedResponse>
@GET("search")
suspend fun getReedData(@Query("keywords") keywords: String,
@Query("locationName") locationName: String, @Query("locationName") locationName: String,
@Query("minimumSalary") minimumSalary: String) : Response<ReedResponse> @Query("minimumSalary") minimumSalary: String) : Response<ReedResponse>
@GET("search")
suspend fun getReedData(@Query("keywords") keywords: String,
@Query("locationName") locationName: String,
@Query("minimumSalary") minimumSalary: String,
@Query("resultsToSkip") resultToSkip: Int) : Response<ReedResponse>
//instantiate api class //instantiate api class
companion object{ companion object{
operator fun invoke() : ReedApi{ operator fun invoke() : ReedApi{