我只能追踪this link来解决我的问题。我正在尝试使用量角器来运行e2e测试。这是我的第一次,我喜欢它。但是我的项目需要Google身份验证,然后经过身份验证后,我会将其与我的数据库进行比较,以确保用户在项目中。我无法从stackoverflow帖子中弄清楚如何调用Google Auth页面对象demee在最后一个答案中正在讨论。另外第一个人说找到元素by.id('电子邮件')和by.id(' Passwd')这可能是一个问题,因为我的谷歌认证正在另一个窗口。因此我不确定如何使用Protractor调用它。这是我加载gapi后初始化$ window后的一些代码:
.controller('ContainerController', ['$scope', '$rootScope', '$state','$window', '$location','employeeFactory', 'employeeTestFactory', function ($scope, $rootScope, $state, $window,$location, employeeFactory, employeeTestFactory) {
$rootScope.callRequests=function(){};
$rootScope.callInfo=function(){};
if(typeof $rootScope.gapi !== "undefined")gapi.load('client:auth2', initClient);
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
if(typeof $rootScope.gapi === "undefined") return;
gapi.load('client:auth2', initClient);
})
$scope.$state = $state;
$window.initGapi = function() {
gapi.load('client:auth2', initClient);
$rootScope.gapi = gapi;
}
$rootScope.calculateUsed = function(val){
$rootScope.employee.timePending = $rootScope.employee.timePending = 0;
var newTimeUsed = 0;
angular.forEach(val, function(key, value){
var td = key.timeDuration;
if(key.timeState === "pending"){
$rootScope.employee.timePending += Number(td);
}else{
newTimeUsed += Number(td);
}
});
$rootScope.employee.totalTimeUsed = newTimeUsed;
}
$scope.employeeType = $rootScope.email = "";
function initClient() {
gapi.client.init({
apiKey: 'AIzaSyDaMf0eviuFygt1hzwQz03a2k2lrLDnpIc',
discoveryDocs: ["https://people.googleapis.com/$discovery/rest?version=v1"],
clientId: '977491754644-954b83j2evmq65v6kchq4dsd9j0ud4vg.apps.googleusercontent.com',
scope: 'profile'
}).then(function () { gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
$scope.employee = [];
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
getEmailAddress();
}else{
$state.go('app');
}
}
$scope.handleSignInClick = function(event) {
if(!gapi.auth2.getAuthInstance().isSignedIn.get()){
gapi.auth2.getAuthInstance().signIn();
}
}
$scope.handleSignOutClick = function(event) {
if(gapi.auth2.getAuthInstance().isSignedIn.get()){
gapi.auth2.getAuthInstance().signOut();
}
}
function getEmailAddress() {
gapi.client.people.people.get({
resourceName: 'people/me'
}).then(function(response) {
$rootScope.email = response.result.emailAddresses[0].value;
$rootScope.callRequests();
$rootScope.callInfo();
//Here is where I compare google to my db and route users back to main if not in db employeeTestFactory.get($rootScope.email).then(function(message) {
if(typeof message.employeeid === "undefined"){
$state.go('app');
}else if($location.path() === "/"){
$state.go('app.employee');
$rootScope.employee = message;
}else{
$rootScope.employee = message;
}
});
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
}
}])
.controller('LoginController', ['$scope', '$state', '$window', '$http','$rootScope', '$timeout', 'GooglePlus', 'gapiService', function ($scope, $state, $window, $http, $rootScope, $timeout, GooglePlus, gapiService) {
$scope.$state = $state;
$scope.callme = function(){
$scope.handleSignInClick();
}
// if it could not be loaded, try the rest of
// the options. if it was, return it.
var url;
var windowThatWasOpened;
$http.get("url").then(function(response) {
url = response.data;
});
$scope.login = function() {
windowThatWasOpened = $window.open(url, "Please sign in with Google", "width=500px,height=700px");
}
window.onmessage = function(e) {
if(windowThatWasOpened) windowThatWasOpened.close();
var urlWithCode = e.data;
var idx = urlWithCode.lastIndexOf("code=");
if(idx === -1) return;
var code = urlWithCode.substring(idx + 5).replace("#","");
$http.get("token?code=" + code).then(function(response) {
var userurl = 'https://www.googleapis.com/plus/v1/people/me?access_token='+response.data.access_token;
$http.get(userurl).then(function(response) {
console.log("user info: "+JSON.stringify(response.data));
})
});
}
}])
这是我试图导航到谷歌的代码:
describe('Protractor Demo App', function() {
it('should have a title', function() {
browser.get('http://localhost:9000/');
element(by.id('gLogin')).click().then(function(){
Google.loginToGoogle();
});
expect(browser.getTitle()).toEqual('TrinityIT Time Off Tracking');
browser.sleep(5000);
});
});
这是我的conf文件:
exports.config = {
framework: 'jasmine',
specs: ['googlePage.js','spec.js'],
onPrepare: function () {
global.isAngularSite = function (flag) {
console.log('Switching to ' + (flag ? 'Asynchronous' : 'Synchronous') + ' mode.')
browser.ignoreSynchronization = !flag;
},
global.BROWSER_WAIT = 5000;
}
}
答案 0 :(得分:3)
假设您要查看的内容是测试您的应用,而不是测试OAuth对话,那么有一种更简单的方法。
首先是OAuth复习,完成所有OAuth工作的重点在于您最终获得了一个访问令牌,您可以将其包含为"授权:Bearer xxxxx"带有Google API的HTTP标头(例如,云端硬盘,YouTube,日历等)请求。 Sooooooo,如果你有一个访问令牌,你可以绕过所有的OAuth东西,你的应用程序将是活跃的,并且能够进行测试。
所以,你想要的是一种获取访问令牌的自动方式。这非常简单。在某处,无论是在您的应用程序代码中还是在您的Protractor前导码脚本中,您都需要获取刷新令牌,并使用它来生成可供您的应用使用的访问令牌。
我使用文件refreshtoken.js
执行此操作,出于安全原因,我小心不要检查git。 refreshtoken.js
是
var refreshtoken="1x97e978a7a0977...";
var client_id="423432423@gfgfd";
如果查看How do I authorise an app (web or installed) without user intervention? (canonical ?)的答案,您将看到获取刷新令牌的步骤,并在底部看到一些JavaScript,以显示如何使用刷新令牌获取访问令牌。它可能看起来像很多步骤,但你只做过一次,所以它不会太繁重。
这种方法绕过了OAuth,如果它是您要测试的特定OAuth,则不是答案。但是它确实允许您以更加健壮的方式测试您的应用程序。它还具有可用于Karma单元测试以及Protractor e2e测试的优点。